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
- wait 和 sleep 都可以使线程进入阻塞状
- wait 和 sleep 都是可中断方法,被中断后都会抛出中断异常并擦除interrupt标志
- wait是object的方法,sleep是Thread的方法
- wait必须在同步代码块中使用,sleep则不需要
- 线程在同步方法中执行sleep方法时并不会释放monitor的锁,而wait会释放掉
- sleep短暂休眠后会自动结束阻塞,wait方法在没有指定timeout的时候会一直处于阻塞状态知道被其他线程调用notify或者notifyAll才能退出阻塞
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!