原文:http://www.java67.com/2012/08/what-are-difference-between-wait-and.html
Wait vs sleep
在Java多线程面试里面,经常被问到wait() 和 sleep() 的区别。虽然 wait 和 sleep 都能将线程状态变成等待状态,但是它们在行为和使用方式上完全不一样的。Thread.sleep(long millis) 会暂停、释放CPU资源和给其他线程有执行的机会,而wait用于Java线程之间的通信。wait方法定义在java.lang.Object类里面,也就是说每个对象都能使用到。这是以对象锁为基础的,如果你记得在Java里面每一个对象都有隐藏锁,也叫监视器(monitor)。当一个线程进入一个synchronized方法的时候它会获得一个当前对象的锁,而当进入的是静态(static)的synchronized方法的时候获得的是这个类的锁。使用wait()和notify()这两个方法可以使得两个线程之间进行通信,这也是解决很多多线程问题的关键,比如生产者-消费者问题,哲学家就餐问题,读和写的问题和实现一些并发的设计。
在这个教程,你会学到下列关于wait()和sleep()方法的问题:
1、什么是wait()方法?
2、什么是sleep()方法?
3、它们之间有什么区别?
4、在什么地方使用到wait和sleep?
话说,如果你是在准备面试Java的话我建议你还是看一下Java Programming Interview Exposed,一本非常不错的Java面试书籍。
Java里面的wait和sleep方法是什么
wait方法定义在Object类里面,所有对象都能用到,在线程通信中,wait()方法经常与notify()和notifyAll()方法一起使用。
当达到某种状态的时候,wait()方法让线程进入等待状态,比如生产者-消费者问题中,当队列满了的时候,生产者这时候需要等待,同样,当队列空的时候,消费者也需要等待。
notify()方法用于唤醒正在等待的线程,这个线程即将停止等待的状态,比如生产者线程往空队列里面增加一个元素,此时notify方法会通知消费者线程这个队列不再为空。另外,sleep()方法在Java应用中用于暂停线程。
当一个线程不用做其他事了,你可以调用sleep方法将线程睡眠,它会在一定时间内放弃当前的CPU资源。当一个线程已经是睡眠状态的时候一段时间后它会正常的唤醒,也可以通过线程中断的特殊方式将它唤醒。
Java线程中wait和sleep方法的区别
在最后一部分中我们可以看到什么是wait()和sleep()和它们之间的区别。正如我之前所说,除了等待之外,它们是完全不同的:
1)第一个很重要的区别就是,wait方法必须正在同步环境下使用,比如synchronized方法或者同步代码块。如果你不在同步条件下使用,会抛出IllegalMonitorStateException异常。另外,sleep方法不需要再同步条件下调用,你可以任意正常的使用。
2)第二个区别是,wait方法用于和定义于Object类的,而sleep方法操作于当前线程,定义在java.lang.Thread类里面。
3)第三个区别是,调用wait()的时候方法会释放当前持有的锁,而sleep方法不会释放任何锁。
4)wait方法最好在循环里面调用,是为了处理错误的通告,比如说,即使线程唤醒了,等待状态仍然适用。(看不懂?大概是循环里面再判断一次线程是否真的醒来),然而sleep方法没这样的限制。最好别在循环里面调用sleep方法。
下面是关于调用wait和sleep方法的代码片段:
```
synchronized(monitor){
while(condition ==true){monitor.wait())//releases monitor lock
}
Thread.sleep(100);//puts current thread on Sleep
```
5)还有一个很大的区别是,一个是静态方法,一个不是。
什么时候用wait和sleep方法?
从阅读wait和sleep方法相关属性和行为说明可以清楚的知道,wait()方法通常结合notify()或者notifyAll()方法在两个线程通信中使用,而Thread.sleep()方法是个让程序或者线程暂停的的工具方法。wait方法的调用需要同步环境这个必要条件才能进行,而sleep方法不需要。
完整的总结一下wait和sleep方法的区别和不同的使用场景。一般wait()和notify()方法使用于线程间的通信;sleep()方法用于暂停当前线程的执行。同时要注意,wait()方法会释放锁,而sleep()方法会一直持有锁(直到睡眠结束)。所以如果你的设计中线程等待需要释放锁的话使用wait方法和nofity方法,否则使用sleep()方法.
结尾
第一次翻译文章,翻译有点生硬,望见谅,也欢迎指出翻译不妥之处。