JDK1.5.0的API文档里的描述:java
yield:Causes the currently executing thread object to temporarily pause and allow other threads to execute.缓存
sleep:Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds.函数
根本无助于理解二者间的差异oop
线程的生命周期里有三个状态Runable、Blocked、Runningthis
yield:Running -> Runablespa
sleep: Running -> Blocked -> Runable.net
yield和sleep都是在线程处于Running的时候开始的,yield只是让出分配给本身的CPU时间片,而且会马上进入Runable状态参与CPU时间的竞争,若程序中没有其余线程,那么该线程立刻就会开始往下执行;sleep会进入Blocked状态,等待时间结束事件的发生,而后进入Runable状态参与CPU时间的竞争线程
调用yield的时候锁并无被释放code
另外,sleep和yield都不具有同步语义,也就是说编译器在执行sleep或yield方法以前和以后,都没有强制要求同步本地缓存与主存的数据对象
如下摘自JSL3.0
It is important to note that neither Thread.sleep nor Thread.yield have
any synchronization semantics. In particular, the compiler does not have to flush
writes cached in registers out to shared memory before a call to Thread.sleep or
Thread.yield, nor does the compiler have to reload values cached in registers
after a call to Thread.sleep or Thread.yield.
For example, in the following (broken) code fragment, assume that this.done is a non-volatile
boolean field:
[java] view plaincopy
The compiler is free to read the field this.done just once, and reuse the cached value
in each execution of the loop. This would mean that the loop would never terminate, even if
another thread changed the value of this.done.
sleep:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操做受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
经过调用sleep使任务进入休眠状态,在这种状况下,任务在指定的时间内不会运行。
调用sleep的时候锁并无被释放。
休眠
Java SE5引入了更加显示的sleep()版本做为TimeUnit类的一部分,这个方法容许你指定sleep()延迟的时间单元,所以能够提供更好的可阅读性。TimeUnit还能够被用来执行转换,就想稍后你会在本书中看到的那样。
wait:调用wait使线程挂起,知道线程获得了notify或notifyAll消息,线程才会进入就绪状态。
使你能够等待某个条件发生变化,而改变这个条件超出了当前方法的控制能力。
线程的执行被挂起,对象上的锁被释放。意味着另外一个任务能够得到这个锁。所以在改对象中的其余synchronized方法能够在wait期间被调用。
就意味着生命“我已经刚刚作完能作的全部事情,所以我要在这里等待,可是我但愿其余synchronized操做在条件适合的状况下才可以执行”
yield:若是知道已经完成了在run()方法的循环的一次迭代过程当中所须要的工做,就能够给线程调度一个机制暗示:个人工做已经作的差很少了,可让给别的线程使用CPU了。经过调用yield()来实现。
当调用yield时,你也是在建议具备相同优先级的其余线程能够运行。
对于任何重要的控制或在调整应用时,都不恩那个依赖于yield。实际上,yield常常被误用。
(yield并不意味着退出和暂停,只是,告诉线程调度若是有人须要,能够先拿去,我过会再执行,没人须要,我继续执行)
调用yield的时候锁并无被释放。
interrupt:中断线程。
中断
Thread.interrupt()或者新类库里面经过Executor的submit()来得到Future<?>返回值,这个Future提供cancel()以中止这个线程。
Thread类包含interrupt()方法,所以你能够终于被阻塞的任务,这个方法将设置线程的中断状态。若是一个线程已经被阻塞,或者视图执行一个阻塞操做,那么设置这个线程的终端状态将抛出InterruptedException。当抛出该异常或者该任何调用Thread.interrupted()时,中断状态将复位。
你在Executor上调用shutdownNow(),那么它将发送一个interrupt()调用给他启动的全部线程。
1.sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。
sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
2.wait()方法
在其余线程调用对象的notify或notifyAll方法前,致使当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
当前线程必须拥有当前对象锁。若是当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。
唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,不然也会抛出IllegalMonitorStateException异常。
waite()和notify()必须在synchronized函数或synchronized block中进行调用。若是在non-synchronized函数或non-synchronized block中进行调用,虽然能编译经过,但在运行时会发生IllegalMonitorStateException的异常。
3.yield方法
暂停当前正在执行的线程对象。
yield()只是使当前线程从新回到可执行状态,因此执行yield()的线程有可能在进入到可执行状态后立刻又被执行。
yield()只能使同优先级或更高优先级的线程有执行的机会。
4.join方法
等待该线程终止。
等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,致使结果不可预测。
publicclass Test { publicstaticvoid main(String[] args) { Thread t1 = new MyThread1(); t1.start(); for (int i = 0; i < 20; i++) { System.out.println("主线程第" + i +"次执行!"); if (i > 2)try { //t1线程合并到主线程中,主线程中止执行过程,转而执行t1线程,直到t1执行完毕后继续。 t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } } class MyThread1 extends Thread { publicvoid run() { for (int i = 0; i < 10; i++) { System.out.println("线程1第" + i + "次执行!"); } } }