Java并发编程深入学习—— sleep和wait的区别

来源:互联网 发布:天刀真武男性捏脸数据 编辑:程序博客网 时间:2024/06/09 08:26

概念

sleep()方法:该方法是属于Thread类中的。

wait()方法:属于Object类,属于Object类的9大方法之一。

以下是JDK 1.6官方文档中对于wait方法和sleep方法的说明。

wait

public final void wait() throws InterruptedException
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用notify 方法,或notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:
synchronized (obj) {while (<condition does not hold>)obj.wait();... // Perform action appropriate to condition     } 
此方法只应由作为此对象监视器的所有者的线程来调用。有关线程能够成为监视器所有者的方法的描述,请参阅 notify 方法。
抛出:
IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。
InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。

sleep

public static void sleep(long millis) throws InterruptedException
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。

参数:
millis - 以毫秒为单位的休眠时间。
抛出:
InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持着,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

什么意思呢?

举个列子说明:

/** * java中的sleep()和wait()的区别 */public class TestD {public static void main(String[] args) {new Thread(new Thread1()).start();try {Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}new Thread(new Thread2()).start();}private static class Thread1 implements Runnable {@Overridepublic void run() {synchronized (TestD.class) {System.out.println("enter thread1...");System.out.println("thread1 is waiting...");try {// 调用wait()方法,线程会放弃对象锁,进入等待此对象的等待锁定池TestD.class.wait();} catch (Exception e) {e.printStackTrace();}System.out.println("thread1 is going on ....");System.out.println("thread1 is over!!!");}}}private static class Thread2 implements Runnable {@Overridepublic void run() {synchronized (TestD.class) {System.out.println("enter thread2....");System.out.println("thread2 is sleep....");// 只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。TestD.class.notify();try {Thread.sleep(5000);} catch (Exception e) {e.printStackTrace();}System.out.println("thread2 is going on....");System.out.println("thread2 is over!!!");}}}}


运行效果:

enter thread1...thread1 is waiting...enter thread2....thread2 is sleep....thread2 is going on....thread2 is over!!!thread1 is going on ....thread1 is over!!!

如果注释掉代码:

1 TestD.class.notify();

运行效果:

enter thread1...thread1 is waiting...enter thread2....thread2 is sleep....thread2 is going on....thread2 is over!!!

且程序一直处于挂起状态。

0 0