【线程】拎清Thread.yield()、sleep()、join()

29 阅读3分钟

1. 区别:

方法区别
yield()静态方法,仅仅给cpu的调度器一个通知,表明可以让出cpu时间片,暂停执行。cpu资源充足时,会忽视该通知
sleep()静态方法,暂停指定时间间隔,不会让出cpu时间片,会阻塞当前线程
join()静态方法,等待线程任务执行完成后,再执行主线程任务,可以设置超时时间。本质上是调用Object.wait方法,会持有对象锁,让出cpu时间片。要靠其他线程调用notify()或者notifyAll()方法来唤醒或者过了设置的等待时间。

2. 知识来源

遇到不会的东西时,我们一般情况下都直接问度娘,奈何各种博客资料太多,质量参差不齐。一般情况下,我会优先通过以下两种方法获取知识:

  • 现在AI大模型遍地跑,直接问AI。我经常用百度的文心一言。
  • 看官方文档,如本篇文章几个方法的区别,我就是优先看了JDK的注释文档,再辅以其他资料理解。英文看不懂?翻译工具太多了,我目前用的是IDEA的翻译插件:Translation 效果如下:

image.png 当然软件直译有时候不太符合咱们的大白话理解,这时候我们自己过一遍,翻译成自己的大白话,再写一篇博客或者总结文档,自己的理解都上升了一个档次! 强烈推荐

  • 当上面两种方法效果都不行时,我才选择度娘。

3. 源码注释阅读-加深理解

yield()方法

/**
 * A hint to the scheduler that the current thread is willing to yield
 * its current use of a processor. The scheduler is free to ignore this
 * hint.
 * 给调度器(cpu的)一个通知:当前线程将要放弃当前进程(执行当前线程逻辑的cpu进程)
 * 当调度器可以自由的忽视这个通知
 *
 * <p> Yield is a heuristic attempt to improve relative progression
 * between threads that would otherwise over-utilise a CPU. Its use
 * should be combined with detailed profiling and benchmarking to
 * ensure that it actually has the desired effect.
 * Yield是一种尝试提升相关线程之间的处理效率的探索,否则线程空闲时也独占cpu进程
 * 会造成cpu的过渡使用。Yield的使用,应该结合基准测试和详细分析来确保实际有效。
 *
 * <p> It is rarely appropriate to use this method. It may be useful
 * for debugging or testing purposes, where it may help to reproduce
 * bugs due to race conditions. It may also be useful when designing
 * concurrency control constructs such as the ones in the
 * {@link java.util.concurrent.locks} package.
 * 在一般情况使用该方法都不是很恰当。在一些情况下,该方法可以帮你复现一些只有在
 * 特殊场景下才可能出现的bug。同样在设计一些并发控制结构的逻辑也是很有用的,如
 * {@link java.util.concurrent.locks}包。
 * 
 */
public static native void yield();

sleep()方法

/**
 * Causes the currently executing thread to sleep (temporarily cease
 * execution) for the specified number of milliseconds, subject to
 * the precision and accuracy of system timers and schedulers. The thread
 * does not lose ownership of any monitors.
 * 会使当前执行的线程睡眠指定毫秒数(仅仅暂停执行),暂停的时间的精度和准确性取决于
 * 当前系统的计时器和内核调度器。当前线程不会丢失(cpu)控制权
 *
 * @param  millis
 *         the length of time to sleep in milliseconds
 *
 * @throws  IllegalArgumentException
 *          if the value of {@code millis} is negative
 *
 * @throws  InterruptedException
 *          if any thread has interrupted the current thread. The
 *          <i>interrupted status</i> of the current thread is
 *          cleared when this exception is thrown.
 *          如果当前线程被设置了中断信号为true(即调用了Thread.interrupt)
 *          会抛出该异常。抛出该异常后,当前线程的“中断信号”会重新置为false
 */
 public static native void sleep(long millis) throws InterruptedException;