sleep执行后线程进入阻塞状态
yield执行后线程进入就绪状态
join执行后线程进入阻塞状态
一、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.
* 意思是说:当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。 该线程不会失去任何监视器的所有权。
* @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.
*/
public static native void sleep(long millis) throws InterruptedException;
其实主要的就是他是让其他线程走,自己进行休眠,但是自己却不会释放对象锁,也就是说,如果有同步锁的时候,其他线程不能访问共享数据。
如果调用了sleep方法,必须捕获InterruptedException异常或者将该异常向上层抛出; sleep方法不会释放该线程所拥有的资源(例如:锁)。(也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。)
总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的 线程有执行的机会。
二、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.
* 意思是说 提示当前线程可以让处理器忽略当前线程,去处理其他线程
* <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.
* 它是一种启发式尝试,用于改善线程之间的相对进展,否则会过度利用CPU。 它的使用应与详细的分析和基准测试相结合,以确保它实际上具有所需的效果。
* <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. * 使用这种方法很少是合适的。 它可能对调试或测试目的很有用,它可能有助于重现因竞争条件而产生的错误。 在设计并发控制结构(如中的那些)时,它也可能很有用
*/
public static native void yield();
yield() 这个方法从以上注释可以看出,也是一个休眠自身线程的方法,同样不会释放自身锁的标识,区别在于它是没有参数的,即yield()方 法只是使当前线程重新回到可执行状态,
所以执行yield()的线程有可能在进入到可执行状态 后马上又被执行,另外yield()方法只能使同优先级或者高优先级的线程得到执行机会,这也 和sleep()方法不同。
调用yield()方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新得到 CPU 的执行;但有可能没有效果。
三、join()方法
看一下源码
当前线程调用其他线程的join方法,会阻塞当前线程,直到其他线程执行完毕,才会进入就绪状态。
join方法是被Synchronized关键字所修饰,访问时,需要获得其他线程对象的锁,如果有两个线程同时调用另外一个线程的join方法,会有一个线程成功得到锁,而另外一个则必须等待,进入阻塞状态,而在得到锁之后,才会执行join方法。
join()方法是通过wait()方法 (Object 提供的方法) 实现的。当 millis == 0 时,会进入 while(isAlive()) 循环,并且只要子线程是活的, 宿主线程就不停的等待。 join方法同样会会让线程交出CPU执行权限; join方法同样会让线程释放对一个对象持有的锁;