wait和notify

wait和notify

  • Object的wait方法会导致当前线程进入阻塞,直到有其他线程调用notify或者notifyAll将其唤醒,或者阻塞时间到达timeout而自动唤醒

    调用notify唤醒线程时不同的JVM实现是不同的, 官方的JVM是按照进入wait set的顺序进行唤醒的(将线程从wait set中进行弹出),如果是notifyAll则是将wait set中所有的唤醒

    唤醒过后线程不会立马接着执行,唤醒过后线程会继续竞争CPU,竞争到后会继续沿着wait执行,所以这里虽说有同步机制还是会有可能产生数据一致性问题,所以在并发编程里不建议使用if判断,建议改为while,因为在你第一次进入执行单元的时候你可能是满足if里面的条件的,但是当你被唤醒后你是接着从wait开始执行的,这时候你是不一定还满足条件的,但是if只会判断那一次,所以会出问题,while的话唤醒后会重新判断条件

  • wait方法必须拥有该对象的monitor所有权, 也就是必须在同步方法中使用

  • 当前线程执行了该对象的wait方法后,就会放弃该对象的monitor,进入到wait set中。其他线程开始继续争抢该对象的所有权

  • 同步代码的monitor必须和调用notify和wait的monitor一致,简单来说就是用哪个对象的monitor进行同步, 就要使用哪个对象的monitor进行wait,notify操作

wait 和 sleep

  1. wait 和 sleep 都可以使线程进入阻塞状
  2. wait 和 sleep 都是可中断方法,被中断后都会抛出中断异常并擦除interrupt标志
  3. wait是object的方法,sleep是Thread的方法
  4. wait必须在同步代码块中使用,sleep则不需要
  5. 线程在同步方法中执行sleep方法时并不会释放monitor的锁,而wait会释放掉
  6. sleep短暂休眠后会自动结束阻塞,wait方法在没有指定timeout的时候会一直处于阻塞状态知道被其他线程调用notify或者notifyAll才能退出阻塞

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!