疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

wait、sleep、notify、notifyAll的区别


 

   

  wait

  导致当前的线程等待,直到其他线程调用此对象的 notify方法或 notifyAll 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行

  sleep

  在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。该线程不丢失任何监视器的所属权。

  wait与sleep

  Wait是Object类的方法,范围是使该Object实例所处的线程。

  Sleep()是Thread类专属的静态方法,针对一个特定的线程。

  Wait方法使实体所处线程暂停执行,从而使对象进入等待状态,直到被notify方法通知或者wait的等待的时间到。Sleep方法使持有的线程暂停运行,从而使线程进入休眠状态,直到用interrupt方法来打断他的休眠或者sleep的休眠的时间到。Wait方法进入等待状态时会释放同步锁(如上例中的lock对象),而Sleep方法不会释放同步锁。所以,当一个线程无限Sleep时又没有任何人去interrupt它的时候,程序就产生大麻烦了notify是用来通知线程,但在notify之前线程是需要获得lock的。另个意思就是必须写在synchronized(lockobj) {...}之中。wait也是这个样子,一个线程需要释放某个lock,也是在其获得lock情况下才能够释放,所以wait也需要放在synchronized(lockobj) {...}之中。

  Sleep与interrupt

  interrupt是个很暴力的方法,打断一个线程的Sleep时并不需要获得该线程的lock。虽然暴力却也有暴力的用处。在一个线程无时限sleep的时候也只有interrupt能够唤醒他。在interrupt的时候会抛出InterruptedException,这个Exception是由Thread 类自动抛出的。因此Interrupt带有强烈的阻塞味道。

  wait与interrupt

  interrupt同样可以打断wait的等待,与打断sleep不同的是,被打断的wait的线程在重新获得lock之前是不会抛出InterruptedException。

  resume和suspend已经被Java遗弃,因为他们天生会引起线程的死锁。

  suspend是个贪婪的家伙,当一个线程在suspend的时候,线程会停下来,但却仍然持有在这之前获得的锁定。其他线程无法使用他锁定的任何资源,除非这个挂起的线程被resume之后,他才会继续运行。对于线程的同步,使用wait与notify要安全的多。