当前位置: 首页 > 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…...

【ACM出版,EI稳定检索,九大高校联合举办, IEEE Fellow支持】2024年计算机视觉与艺术研讨会(CVA 2024)

在线投稿&#xff1a;学术会议-学术交流征稿-学术会议在线-艾思科蓝 2024年计算机视觉与艺术国际学术会议&#xff08;CVA 2024&#xff09;作为2024年人工智能、数字媒体技术与交互设计国际学术会议&#xff08;ICADI 2024)的分会。此次大会旨在汇聚全球在计算机视觉与艺术…...

认识软件测试

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 软件测试专栏:软件测试 关注博主带你了解更多知识 1. 什么是测试&#xff1f; 测试在⽣活中处处可⻅ 例子: 对某款购物软件进⾏测试 启动测试&#xff1a;点击软件图标&#…...

poi处理excel文档时,与lombok的@Accessors(chain = true)注解冲突

poi在反射封装数据时会判断set方法的返回是不是Void&#xff0c;加上Accessors会造成NoSuchMethodException异常...

我接触csdn中的c++的时间

大家好&#xff0c;我是AC使者&#xff0c;不知不觉我也来到CSDN半年了&#xff01;在这半年我也看到了自身的不足&#xff0c;我也还有了很多粉丝&#xff0c;所以我今天来总结一下这半年的东西。 第一篇--------结构体数组 关于结构体数组的理解-CSDN博客 第二篇--------字…...

go语言多态性(接口interface)的使用

前言 在Go语言中&#xff0c;接口类型&#xff08;interface&#xff09;完全可以作为一个函数的参数。这是Go语言多态性的一个重要体现&#xff0c;允许函数接受任何实现了接口中定义的方法的类型的实例。 一、接口&#xff08;interface&#xff09;定义 type Reader inte…...

如何将markdown文件转换为pdf

最近笔者在用vscode写markdown&#xff0c;但是提交时往往需要交pdf。所以就涉及到如何将markdown转化为pdf格式。 首先&#xff0c;需要在vscode上安装插件 markdown Preview Enhanced 之后在vscode的右上角即可看到下述图标&#xff0c;点击&#xff0c;vscode右半面就会显示…...

【python实操】python小程序之测试报告

引言 python小程序之测试报告 文章目录 引言一、测试报告1.1 概念1.1.1 使用Pytest和Allure生成测试报告1.1.2 使用unittest和HTMLTestRunner生成测试报告1.1.3 总结 1.2 题目1.3 代码1.3 代码解释 二、思考 一、测试报告 1.1 概念 python生成测试报告&#xff0c;常用的方法包…...

【Java基础】2、Java基础语法

f2/fnf2&#xff1a;选中点中的文件名 ​​​​​​​ 1.注释 为什么要有注释&#xff1f; 给别人和以后的自己可以看懂的解释 注释含义 注释是在程序指定位置的说明性信息&#xff1b;简单理解&#xff0c;就是对代码的一种解释 注释分类 单行注释 //注释信息 多行注释…...

MATLAB基础应用精讲-【数模应用】本量利分析(Cost-Volume-Profit Analysis)

目录 前言 几个高频面试题目 本量利分析与量本利分析的区别 算法原理 发展历程 几个相关概念 什么是CVP分析 基本假设 注意事项 本量利分析的作用 基本原理 多种产品量本利分析 盈亏平衡分析 目标利润分析 敏感性分析 边际分析 本量利分析基本模型 应用场景 …...

实习冲刺Day7

算法题 合并两个有序链表 class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {for (int i 0; i<n; i) {nums1[m i] nums2[i];//直接将num2的数据插入到num1的尾部}sort(nums1.begin(), nums1.end());//排…...

wordpress简单主题下载/百度点击率排名有效果吗

Reactor Model Introduction Reactor模型是一种在事件模型下的并发编程模型。 Reactor模型首先是一个概念模型&#xff1b;它可以描述在Node.js中所有的并发和异步编程行为&#xff0c;包括基础的异步API&#xff0c;EventEmitter对象&#xff0c;以及第三方库或实际项目中的已…...

wordpress邮件验证评论/网站推广优化排名公司

一 kafka消费端的参数 二 实现案例 2.1 订阅某个主题 创建一个独立消费者&#xff0c;消费 kafka-ljf主题中数据。 注意&#xff1a;在消费者 API 代码中必须配置消费者组 id。命令行启动消费者不填写消费者组 id 会被自动填写随机的消费者组 id。 2.消费者代码package com.lj…...

java做网站需要的技术/百度网首页登录入口

昨天花了一个下午才升级成功&#xff0c;今天费了点儿周折才打上补丁&#xff0c;不想同道中人再浪费不必要的时间&#xff0c;把以把我的步骤给大家说一下&#xff0c;供参考。 使用工具:x65Flasher与VK 升级文件及工具下载:http://yizhe.net/c65/ 步骤&#xff1a; 1.关机&am…...

php网站开发说明文档/爱链网中可以进行链接买卖

8个动态数码管时钟显示#include#define uint unsigned int#define uchar unsigned charuchar i,temp,aa,miao,fen,shi,play0;/************************************************定义3个键&#xff0c;K1用于调节分&#xff0c;K2用于调节时&#xff0c;K3用于调节时**********…...

php做动态网站/seo搜索引擎优化技术

SQL Server 数据库启动过程&#xff0c;以及启动不起来的各种问题的分析及解决技巧参考文章&#xff1a; &#xff08;1&#xff09;SQL Server 数据库启动过程&#xff0c;以及启动不起来的各种问题的分析及解决技巧 &#xff08;2&#xff09;https://www.cnblogs.com/VicL…...

网站建设哪个品牌好/2345网址导航下载桌面

题目背景 大家都知道&#xff0c;基因可以看作一个碱基对序列。它包含了444种核苷酸&#xff0c;简记作A,C,G,TA,C,G,TA,C,G,T。生物学家正致力于寻找人类基因的功能&#xff0c;以利用于诊断疾病和发明药物。 在一个人类基因工作组的任务中&#xff0c;生物学家研究的是&#…...