当前位置: 首页 > news >正文

Java Lock LockSupport 源码

前言


 相关系列

  • 《Java & Lock & 目录》(持续更新)
  • 《Java & Lock & LockSupport & 源码》(学习过程/多有漏误/仅作参考/不再更新)
  • 《Java & Lock & LockSupport & 总结》(学习总结/最新最准/持续更新)
  • 《Java & Lock & LockSupport & 问题》(学习解答/持续更新)
     
     

源码


/** ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************//******* Written by Doug Lea with assistance from members of JCP JSR-166* Expert Group and released to the public domain, as explained at* http://creativecommons.org/publicdomain/zero/1.0/*/package juc.locks;import juc.Semaphore;
import sun.misc.Unsafe;import java.util.concurrent.ThreadLocalRandom;/*** Basic thread blocking primitives for creating locks and other synchronization classes.* 用于创建锁和其它同步类的基本线程阻塞原语。* <p>* This class associates, with each thread that uses it, a permit (in the sense of the* {@link Semaphore Semaphore} class). A call to {@code park} will return immediately if the permit is available,* consuming it in the process; otherwise it <em>may</em> block.  A call to {@code unpark} makes the permit available,* if it was not already available. (Unlike with Semaphores though, permits do not accumulate. There is at most one.)* 该类与每个使用它的线程关联一个许可(从信号量类的角度上看)。如果许可可用则调用一次park()方法将立即返回,并* 在过程中消费它;否则它将可能阻塞。如果许可不可用,则调用一次unpark()方法可使得其可用。(但是不像信号量,许* 可无法累积。最多只能有一个。)* <p>* Methods {@code park} and {@code unpark} provide efficient means of blocking and unblocking threads that do not* encounter the problems that cause the deprecated methods {@code Thread.suspend} and {@code Thread.resume} to* beunusable for such purposes: Races between one thread invoking {@code park} and another thread trying to* {@code unpark} it will preserve liveness, due to the permit. Additionally, {@code park} will return if the caller's* threadwas interrupted, and timeout versions are supported. The {@code park} method may also return at any other* time, for "no reason", so in general must be invoked within a loop that rechecks conditions upon return. In this sense* {@code park}serves as an optimization of a "busy wait" that does not waste as much time spinning, but must be* paired with an {@code unpark} to be effective.* 方法park和unpark提供了阻塞和解除阻塞线程的有效方法,这些方法不会遇到导致已弃用方法suspend和resume对于如此* 目的无用的问题:在线程调用park方法与其它线程尝试unpark它之间竞争将由于许可而保持活性。此外,如果调用者的线* 程已被中断,以及支持超时版本则park将返回。park方法也可能在任意其它时间无理由的返回,所以通常必须在返回后检* 查条件的循环中被调用。从这个角度上看park方法作为忙等待的优化手段不会浪费太多自旋时间,但必须与一个unpark方* 法成对使用以令之有效。* <p>* The three forms of {@code park} each also support a {@code blocker} object parameter. This object is recorded while* the thread is blocked to permit monitoring and diagnostic tools to identify the reasons that threads are blocked. (Such* tools may access blockers using method {@link #getBlocker(Thread)}.) The use of these forms rather than the original* forms without this parameter is strongly encouraged. The normal argument to supply as a {@code blocker} within a* lock implementation is {@code this}.* park方法的三种格式每个都支持一个阻塞者对象参数。该对象在线程在线程阻塞期间被记录,以允许监视器和诊断工具识* 别线程阻塞的原因。(该工具可能访问使用getBlocker(Thread)方法访问阻塞者)。强烈鼓励使用这些格式而不是原本没有* 参数的原始格式。该常规参数用于在一个锁实现中供应一个阻塞者。* <p>* These methods are designed to be used as tools for creating higher-level synchronization utilities, and are not in* themselves useful for most concurrency control applications.  The {@code park} method is designed for use only in* constructions of the form:* 这些方法被设计用于作为创建更高等级的同步程序的工具,并且它们本身对于大多数并发控制应用程序并没有用(意思是* 不会在API中使用相应的方法保证线程安全,而是使用基于它们创建的线程安全工具保证线程安全)。park方法被设计只在* 以下格式中构造:* <pre> {@code* while (!canProceed()) { ... LockSupport.park(this); }}</pre>* <p>* where neither {@code canProceed} nor any other actions prior to the call to {@code park} entail locking or blocking.* Because only one permit is associated with each thread, any intermediary uses of {@code park} could interfere with* its intended effects.* 其中即不是canProceed方法也不是任意其它优先于park方法的活动都需要加锁或阻塞(意思是循环中位于park方法之后的* 代码都必须是线程安全的...妈的什么鬼英语)。因为线程只关联一个许可,因此任意park方法的中间调用都会干涉它的预* 期效果(简而言之就是要要避免外部干扰)。** <p>* <b>Sample Usage.</b> Here is a sketch of a first-in-first-out non-reentrant lock class:* 简单用法。这是一个先入先出非重入锁类的草图:* <pre> {@code* class FIFOMutex {*   // ---- 原子布尔,作为锁使用。*   private final AtomicBoolean locked = new AtomicBoolean(false);*   // ---- 等待者队列。*   private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();**   // ---- 加锁。*   public void lock() {*     // ---- 经线程加入等待者集中。*     boolean wasInterrupted = false;*     Thread current = Thread.currentThread();*     waiters.add(current);**     // Block while not first in queue or cannot acquire lock*     // 在非队列首个线程或无法获取锁的情况下阻塞**     while (waiters.peek() != current || !locked.compareAndSet(false, true)) {*       LockSupport.park(this);*       if (Thread.interrupted())*         // ignore interrupts while waiting*         // 忽略在等待期间的中断(即该方法在设计上是不允许被中断的)*         wasInterrupted = true;*     }*     // ---- 退出循环后,将当前线程从等待者集中移除。*     waiters.remove();*     // reassert interrupt status on exit*     // 在退出时重设中断状态。*     if (wasInterrupted)*       current.interrupt();*   }**   public void unlock() {*     locked.set(false);*     // ---- 唤醒等待者集中的首个线程。*     LockSupport.unpark(waiters.peek());*   }* }}</pre>*/
public class LockSupport {/*** @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* ----* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 初始化锁支持者* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ----*/private LockSupport() {// Cannot be instantiated.// 无法(外部)实例化}/*** @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 设置阻塞者* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 为指定线程设置指定阻塞者* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法直接通过CAS操作完成。*/private static void setBlocker(Thread t, Object arg) {// Even though volatile, hotspot doesn't need a write barrier here.// 虽然易变,但热点在这里不需要一个写屏障。UNSAFE.putObject(t, parkBlockerOffset, arg);}/*** Makes available the permit for the given thread, if it was not already available.  If the thread was blocked on* {@code park} then it will unblock.  Otherwise, its next call to {@code park} is guaranteed not to block. This* operation is not guaranteed to have any effect at all if the given thread has not been started.* 如果指定线程尚未可用,则令其许可可用。如果线程它因为park方法而阻塞则它将解除阻塞。否则,它的下次park方* 法调用将不保证阻塞。如果指定线程尚未启动则该操作无法保证在任意情况下都有效果。** @param thread the thread to unpark, or {@code null}, in which case this operation has no effect*               用于释放的线程,或者为null,在该情况下该操作没有效果* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 解除停放* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 为指定线程分配一个许可,如果指定线程因为许可负债(-1)而处于等待状态,则将因为负债被清零而恢复运行;如果* 指定线程因为许可平衡(0)而处于运行状态,则将因为许可结余(1)而不会在下一次许可消耗中进入等待状态。如果* 执行线程尚未启动则上述所有情况都不保证一定会发生。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法直接通过CAS机制实现。*/public static void unpark(Thread thread) {if (thread != null)UNSAFE.unpark(thread);}/*** Disables the current thread for thread scheduling purposes unless the permit is available.* 出于线程调度目的令当前线程无效,除非许可可用。* <p>* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes* disabled for thread scheduling purposes and lies dormant until one of three things happens:* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下三种情况发生:* <ul>* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or* 某些其它线程将当前线程作为目标调用unpark方法;或者* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or* 某些其它线程中断当前线程;或者* <li>The call spuriously (that is, for no reason) returns. </ul>* 该调用虚假地(无理由地)返回。* <p>* This method does <em>not</em> report which of these caused the method to return. Callers should re-check the* conditions which caused the thread to park in the first place. Callers may also determine, for example, the* interrupt status of the thread upon return.* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,* 例如,线程返回后的中断状态。** @param blocker the synchronization object responsible for this thread parking*                该同步对象负责当前线程的停泊* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 停泊* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入无限等待状态;直至因为信号、中断及虚假的原* 因而唤醒;否则直接返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除并返* 回。阻塞者的作用是令唤醒当前线程可以判断是否满足条件,功能是自定义的。* @since 1.6*/public static void park(Object blocker) {// ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除// 并返回。阻塞者的作用是令唤醒当前线程可以判断是否满足条件,功能是自定义的。Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, 0L);setBlocker(t, null);}/*** Disables the current thread for thread scheduling purposes, for up to the specified waiting time, unless the permit* is available.* 出于调度线程的目的令当前线程无效,直至指定等待时间,除非许可可用。* <p>* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes* disabled for thread scheduling purposes and lies dormant until one of four things happens:* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:* <ul>* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or* 某些其它线程将当前线程作为目标调用unpark方法;或者* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or* 某些其它线程中断当前线程;或者* <li>The specified waiting time elapses; or* 指定等待时间消逝;或者* <li>The call spuriously (that is, for no reason) returns. </ul>* 该调用虚假地(无理由地)返回。* </ul>** <p>* This method does <em>not</em> report which of these caused the method to return. Callers should re-check the* conditions which caused the thread to park in the first place. Callers may also determine, for example, the* interrupt status of the thread, or the elapsed time upon return.* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,* 例如,线程返回后的中断状态,或过期时间。** @param blocker the synchronization object responsible for this thread parking*                该同步对象负责当前线程的停泊* @param nanos   the maximum number of nanoseconds to wait*                等待的最大纳秒时间* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 停泊纳秒* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚* 假的原因而唤醒;否则直接返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法首先会判断指定等待时间是否合法,合法则为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进* 入等待状态失败则将阻塞者清除并返回。* @since 1.6*/public static void parkNanos(Object blocker, long nanos) {if (nanos > 0) {Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(false, nanos);setBlocker(t, null);}}/*** Disables the current thread for thread scheduling purposes, until the specified deadline, unless the permit is available.* 出于调度线程的目的令当前线程无效,直至指定死亡线,除非许可可用。* <p>* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes* disabled for thread scheduling purposes and lies dormant until one of four things happens:* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:* <ul>* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or* 某些其它线程将当前线程作为目标调用unpark方法;或者* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or* 某些其它线程中断当前线程;或者* <li>The specified waiting time elapses; or* 指定等待时间消逝;或者* <li>The call spuriously (that is, for no reason) returns. </ul>* 该调用虚假地(无理由地)返回。* </ul>* <p>* This method does <em>not</em> report which of these caused the method to return. Callers should re-check the* conditions which caused the thread to park in the first place. Callers may also determine, for example, the* interrupt status of the thread, or the current time upon return.* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,* 例如,线程返回后的中断状态,或过期时间。** @param blocker  the synchronization object responsible for this thread parking*                 该同步对象负责当前线程的停泊* @param deadline the absolute time, in milliseconds from the Epoch, to wait until*                 从纪元到等待的绝对时间,以毫秒为单位* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 停泊直至* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚* 假的原因而唤醒;否则直接返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除并返* 回。* @since 1.6*/public static void parkUntil(Object blocker, long deadline) {Thread t = Thread.currentThread();setBlocker(t, blocker);UNSAFE.park(true, deadline);setBlocker(t, null);}/*** Returns the blocker object supplied to the most recent invocation of a park method that has not yet unblocked, or* null if not blocked.  The value returned is just a momentary snapshot -- the thread may have since unblocked or* blocked on a different blocker object.* 返回由最近一次还未解除阻塞的park方法调用提供的阻塞者对象,或者如果未阻塞则为null。返回的值只是一个短暂的* 快照-- 该线程可能已解除阻塞或在另一个阻塞对象中阻塞。** @param t the thread 线程* @return the blocker 阻塞者* @throws NullPointerException if argument is null*                              空指针异常:如果参数为null* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 获取阻塞者* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 获取当前线程的阻塞者。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ----* @since 1.6*/public static Object getBlocker(Thread t) {if (t == null)throw new NullPointerException();return UNSAFE.getObjectVolatile(t, parkBlockerOffset);}/*** Disables the current thread for thread scheduling purposes unless the permit is available.* 出于线程调度目的令当前线程无效,除非许可可用。* <p>* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes* disabled for thread scheduling purposes and lies dormant until one of three things happens:* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下三种情况发生:* <ul>* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or* 某些其它线程将当前线程作为目标调用unpark方法;或者* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or* 某些其它线程中断当前线程;或者* <li>The call spuriously (that is, for no reason) returns. </ul>* 该调用虚假地(无理由地)返回。* </ul>** <p>* This method does <em>not</em> report which of these caused the method to return. Callers should re-check the* conditions which caused the thread to park in the first place. Callers may also determine, for example, the* interrupt status of the thread upon return.* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,* 例如,线程返回后的中断状态。** @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 停泊* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入无限等待状态;直至因为信号、中断及虚假的原* 因而唤醒;否则直接返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ----*/public static void park() {UNSAFE.park(false, 0L);}/*** Disables the current thread for thread scheduling purposes, for up to the specified waiting time, unless the permit* is available.* 出于调度线程的目的令当前线程无效,直至指定等待时间,除非许可可用。** <p>* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes* disabled for thread scheduling purposes and lies dormant until one of four things happens:* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:* <ul>* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or* 某些其它线程将当前线程作为目标调用unpark方法;或者* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or* 某些其它线程中断当前线程;或者* <li>The specified waiting time elapses; or* 指定等待时间消逝;或者* <li>The call spuriously (that is, for no reason) returns. </ul>* 该调用虚假地(无理由地)返回。* </ul>** <p>* This method does <em>not</em> report which of these caused the method to return. Callers should re-check the* conditions which caused the thread to park in the first place. Callers may also determine, for example, the* interrupt status of the thread, or the elapsed time upon return.* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,* 例如,线程返回后的中断状态,或过期时间。** @param nanos the maximum number of nanoseconds to wait*              等待的最大纳秒时间* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 停泊纳秒* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚* 假的原因而唤醒;否则直接返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ----*/public static void parkNanos(long nanos) {if (nanos > 0)UNSAFE.park(false, nanos);}/*** Disables the current thread for thread scheduling purposes, until the specified deadline, unless the permit is available.* 出于调度线程的目的令当前线程无效,直至指定死亡线,除非许可可用。* <p>* If the permit is available then it is consumed and the call returns immediately; otherwise the current thread becomes* disabled for thread scheduling purposes and lies dormant until one of four things happens:* 如果许可可用则消费许可并立即返回;否则当前线程处于线程调度目的将变得无效,并且休眠至以下四种情况发生:* <ul>* <li>Some other thread invokes {@link #unpark unpark} with the current thread as the target; or* 某些其它线程将当前线程作为目标调用unpark方法;或者* <li>Some other thread {@linkplain Thread#interrupt interrupts} the current thread; or* 某些其它线程中断当前线程;或者* <li>The specified waiting time elapses; or* 指定等待时间消逝;或者* <li>The call spuriously (that is, for no reason) returns. </ul>* 该调用虚假地(无理由地)返回。* </ul>* <p>* This method does <em>not</em> report which of these caused the method to return. Callers should re-check the* conditions which caused the thread to park in the first place. Callers may also determine, for example, the* interrupt status of the thread, or the current time upon return.* 该方法不会记录什么导致方法返回。调用者首先应该重检查导致线程停泊的条件(是否满足)。调用者可能还要确定,* 例如,线程返回后的中断状态,或过期时间。** @param deadline the absolute time, in milliseconds from the Epoch, to wait until*                 从纪元到等待的绝对时间,以毫秒为单位* @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 停泊直至* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 消耗指定线程的一个许可,消耗后如果指定线程许可负债(-1)则进入有限等待状态;直至因为信号、中断、超时及虚* 假的原因而唤醒;否则直接返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法首先会为指定线程设置阻塞者,随后令之进入等待状态,如果被唤醒或进入等待状态失败则将阻塞者清除并返* 回。*/public static void parkUntil(long deadline) {UNSAFE.park(true, deadline);}/*** Returns the pseudo-randomly initialized or updated secondary seed. Copied from ThreadLocalRandom due to package* access restrictions.* 虚假随机地返回初始化的或更新的次要个种子。由于包访问限制从ThreadLocalRandom中赋值。** @Description: ----------------------------------------------------------- 名称 -----------------------------------------------------------* 下个次要种子* @Description: ----------------------------------------------------------- 作用 -----------------------------------------------------------* 基于当前线程的次要种子生成新的次要种子并保存/返回。* @Description: ----------------------------------------------------------- 逻辑 -----------------------------------------------------------* ---- 方法首先会从当前线程中获取次要种子并判断是否为0,为0表示为初始值,为之随机分配一个值。但为了防止随机* 的数值为0需要在该情况下手动将之赋值为1;如果不为0则说明次要种子已经被更新过,基于其进行位运算已生成新的* 次要种子。* ---- 新的次要种子生成后将之重新保存至当前线程中并返回。*/static final int nextSecondarySeed() {int r;Thread t = Thread.currentThread();if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {// ---- 从线程中获取次要种子,如果不为0,说明已经经历过更新,直接进行位操作。r ^= r << 13;   // xorshiftr ^= r >>> 17;r ^= r << 5;} else if ((r = ThreadLocalRandom.current().nextInt()) == 0)// avoid zero// 避免0// ---- 如果次要种子为0,说明为初始值,尚未经历过更新,因此为之分配一个随机数。但是为了防止其再次为0需// 要在其位0是手动赋值为1。r = 1;// ---- 新的次要种子被分配后,重新保存。UNSAFE.putInt(t, SECONDARY, r);return r;}// Hotspot implementation via intrinsics APIprivate static final Unsafe UNSAFE;private static final long parkBlockerOffset;private static final long SEED;private static final long PROBE;private static final long SECONDARY;static {try {UNSAFE = Unsafe.getUnsafe();Class<?> tk = Thread.class;parkBlockerOffset = UNSAFE.objectFieldOffset(tk.getDeclaredField("parkBlocker"));SEED = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSeed"));PROBE = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomProbe"));SECONDARY = UNSAFE.objectFieldOffset(tk.getDeclaredField("threadLocalRandomSecondarySeed"));} catch (Exception ex) {throw new Error(ex);}}}

相关文章:

Java Lock LockSupport 源码

前言 相关系列 《Java & Lock & 目录》&#xff08;持续更新&#xff09;《Java & Lock & LockSupport & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Java & Lock & LockSupport & 总结》&#xff08;学习总结/最新…...

Elasticsearch基础操作入门

阅前准备知识 学习 Elasticsearch (简称 ES) 的查询方式&#xff0c;建议从以下几个步骤入手&#xff1a; 理解 Elasticsearch 的基础概念 首先要了解 Elasticsearch 的核心概念&#xff0c;例如&#xff1a; Index&#xff08;索引&#xff09;&#xff1a;相当于数据库中…...

跨域问题解决办法

跨域问题在Web开发中是一个常见的问题&#xff0c;特别是在前后端分离的开发模式下。以下是一些解决跨域问题的办法&#xff1a; 一、后端配置CORS&#xff08;跨来源资源共享&#xff09; CORS是一种机制&#xff0c;它使用额外的HTTP头来告诉浏览器一个网页的当前来源&…...

【数据结构与算法】力扣 23. 合并 K 个升序链表

题干描述 23. 合并 K 个升序链表 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 示例 1&#xff1a; 输入&#xff1a; lists [[1,4,5],[1,3,4],[2,6]] 输出&#xff1a; [1,1,2,3,4,4,5,6]…...

Java Lock CountDownLatch 总结

前言 相关系列 《Java & Lock & 目录》&#xff08;持续更新&#xff09;《Java & Lock & CountDownLatch & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Java & Lock & CountDownLatch & 总结》&#xff08;学习总…...

vue+spreadjs开发

创建vue3项目 pnpm create vite --registryhttp://registry.npm.taobao.org安装spreadjs包 pnpm install "grapecity-software/spread-sheets17.1.7" "grapecity-software/spread-sheets-resources-zh17.1.7" "grapecity-software/spread-sheets-vu…...

针对初学者的PyTorch项目推荐

文章目录 1. MNIST手写数字识别2. CIFAR-10图像分类3. 图像风格迁移4. 文本生成&#xff08;使用RNN&#xff09;5. 简单的问答系统6. 简单的生成对抗网络&#xff08;GAN&#xff09;7. 简单的推荐系统 对于初学者来说&#xff0c;选择一些简单且具有教育意义的项目来实践PyTo…...

Helm Chart文件介绍

介绍&#xff08;这个还没有完善 &#xff0c;目前在找工作呢&#xff09; Helm是Kubernetes的包管理器&#xff0c;类似于Ubuntu中的apt、CentOS中的yum或Python中的pip&#xff0c;可以快速查找、下载和安装软件包。Helm主要由客户端组件helm和服务端组件Tiller组成&#xf…...

1Panel 是新一代的 Linux 服务器运维管理面板

1Panel 是一款新一代的 Linux 服务器运维管理面板&#xff0c;旨在通过现代化的 Web 界面帮助用户轻松管理 Linux 服务器。它集成了主机监控、文件管理、数据库管理、容器管理等功能&#xff0c;并且支持多语言和国际化&#xff0c;包括英语、中文(繁体)和日语。以下是 1Panel …...

Qml-ShaderEffect的使用

Qml-ShaderEffect的使用 ShaderEffect的概述 ShaderEffect使用自定义的顶点和片段着色器用于渲染一个矩形。用于在qml场景中添加阴影、模糊、着色和页面卷曲等效果。 Qt5和Qt6中ShaderEffect有一定区别&#xff0c;在Qt6中由于支持不同的渲染API&#xff0c;ShaderEffect是用…...

鸿蒙next之axios二次封装并携带cookie

由于官方提供的ohos.net.http模块&#xff0c;直接使用不是很灵活&#xff0c;就引入了第三方ohos/axios库。 以下是引入axios并进行二次封装的步骤&#xff1a; 1、DevEco Studio打开终端输入命令安装插件 ohpm install ohos/axios 2、新建RequestUtil.ets import { JSON, …...

WordPress中最值得推荐的AI插件:专家级指南

WordPress平台上&#xff0c;人工智能&#xff08;AI&#xff09;技术不断发展&#xff0c;为用户提供了丰富的工具和功能。对于有经验的用户&#xff0c;这些工具不仅能提升网站性能和用户体验&#xff0c;还能在安全和互动方面提供更多支持。在这篇文章中&#xff0c;我将为大…...

HTTP介绍及请求过程

HTTP(HyperText Transfer Protocol),即超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。以下是关于 HTTP 的详细介绍: 一、基本概念 定义与作用: HTTP 是互联网上应用最为广泛的一种网络协议,它定义了客户端和服务器之间请求和响应的标准方式。…...

WebGL进阶(五)-可视域

理论基础&#xff1a; 顶点着色器 Vertex Shader 主要是负责处理顶点位置、顶点颜色、顶点向量等顶点的数据&#xff1b;处理一些顶点的变换&#xff1a;例如在进行视图变换和投影变换时MVP矩阵会改变顶点的位置信息。 输入&#xff1a; 顶点着色器输入部分主要是声明&…...

2024性价比家居好物有哪些?推荐五款值得每个家庭拥有的好物品牌!

每年双11的时候我都特别喜欢买一些家居好物&#xff0c;今年双11也不例外&#xff0c;经过我一两周的精心挑选&#xff0c;专门选了五款性价比高的家居好物&#xff0c;接下来给大家分享一下&#xff01; 家居好物一、希亦ACE Pro内衣洗衣机 我买过、评测过的内衣洗衣机&#…...

字节青训-查找热点数据问题

问题描述 给你一个整数数组 nums 和一个整数 k&#xff0c;请你返回其中出现频率前 k 高的元素。请按升序排列。 1 < nums.length < 10^5k 的取值范围是 [1, 数组中不相同的元素的个数]题目数据保证答案唯一&#xff0c;换句话说&#xff0c;数组中前 k 个高频元素的集合…...

Codeforces Round 981 (Div. 3) (A~F)

文章目录 A. Sakurako and Kosuke思路code B. Sakurako and Water思路code C. Sakurakos Field Trip思路code D. Kousukes Assignment思路code E. Sakurako, Kosuke, and the Permutation思路code F. Kosukes Sloth思路code Codeforces Round 981 (Div. 3) A. Sakurako and Ko…...

shell脚本实例(4)while实现1+...+100,linux新增用户

while实现1到100求和 #!/bin/bash/ s0 i1 #-le小于等于 while [ $i -le 100 ] dos$[ $s$i ]i$[ $i1 ] done echo $s echo $i 执行结果如下 修改用户名密码脚本 #!/bin/bash/ #提示用户输入用户名 read -p "请输入用户名&#xff1a;"username useradd $username #提…...

docker XML详解

下列为一个基本的运行docker镜像文件 {"Id": "62a82b0e69930e54c291095f632adde58dd0b247adba3a048385a55c87e38eba","Created": "2024-07-11T04:00:09.36091853Z","Path": "java","Args": ["-ja…...

web前端边框详解,弹性盒子的使用(仿写购物网页)

边框详解 1. 边框宽度&#xff08;border - width&#xff09; - 具体取值&#xff1a;可以是具体的长度值&#xff0c;如 px &#xff08;像素&#xff09;、 pt &#xff08;点&#xff09;、 em &#xff08;相对单位&#xff09;等。例如&#xff0c; border - width: 2px…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例

目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码&#xff1a;冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

书籍“之“字形打印矩阵(8)0609

题目 给定一个矩阵matrix&#xff0c;按照"之"字形的方式打印这个矩阵&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为&#xff1a;1&#xff0c;…...