为什么Object.wait(),Object.notify(),Object.notifyAll()必须在同步块中执行呢?
2018-03-06 15:58
603 查看
背景介绍
代码示例
静态条件思路
PV操作思路
参考
调用
若
执行上述代码后,结果如下,抛出java.lang.IllegalMonitorStateException:
但是为什么会抛出java.lang.IllegalMonitorStateException呢?
由于
看做P操作.
将
看做V操作,而PV的资源含义则由
由于PV操作必须是原子操作,而若
代码示例
静态条件思路
PV操作思路
参考
背景介绍
在Java中,我们使用wait()和
nofify()或
notifyAll()来实现线程间通信。一个线程在测试条件不满足后进入等待状态。在经典的生产者-消费者问题中,生产者线程因缓存区满而等待,消费者线程在消费了缓存区的一个元素后通知生产者线程。
调用
notify()和
notifyAll()方法来通知一个或多个线程一个条件已经改变了。一旦通知线程退出同步方法或同步块,所有等待的线程会争抢它们等待对象上的对象锁。获取锁的线程会从等待状态返回并继续执行
代码示例
一般而言,使用Object的wait/notify进行现场通信代码如下图示,wait()和
notify()都在同步块中执行.
若
wait()和
notify()不在同步块中执行,会出现什么情况呢?
/** * @author pfjia * @since 2018/3/6 15:40 */ public class IllegalWaitDemo { public static void main(String[] args) { IllegalWaitDemo demo=new IllegalWaitDemo(); try { demo.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }
执行上述代码后,结果如下,抛出java.lang.IllegalMonitorStateException:
Exception in thread "main" java.lang.IllegalMonitorStateException at java.base/java.lang.Object.wait(Native Method) at java.base/java.lang.Object.wait(Object.java:516) at pfjia.IllegalWaitDemo.main(IllegalWaitDemo.java:11)
但是为什么会抛出java.lang.IllegalMonitorStateException呢?
静态条件思路
试想在不加锁时,一个如下的操作顺序生产者 while (!someCondition){ (1) lock.wait(); (4) } 消费者 satisfyCondition(); (2) lock.notify(); (3)
由于
while(!someCondition){lock.wait()}是一个先判断后执行的语句,因此一定存在
竞态条件,当上述代码以标识的顺序执行时,由于在
!someCondition为true后才执行
satisfyCondition()满足该condition,因此将导致即使condition被满足了,
lock.wait()还是会在
lock.notify()之后执行,就相当于丢失了一次唤醒.如果只有一个消费者线程,则生产者将永远得不到唤醒.
PV操作思路
我是将synchronized (lock){ while (!someCondition){ (1) lock.wait(); (4) } }
看做P操作.
将
synchronized (lock){ satisfyCondition(); (2) lock.notify(); (3) }
看做V操作,而PV的资源含义则由
someCondition和
satisfyCondition()确定.
由于PV操作必须是原子操作,而若
wait()和
notify()不在同步块中,就无法保证
原子性,所以
wait()和
notify()必须在同步块中执行.
参考
为什么wait和notify必须在同步方法或同步块中调用相关文章推荐
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- 为什么wait(),notify()和notifyAll()必须在同步块或同步方法中调
- 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- (转)为什么wait(),notify()和notifyAll()必须在同步块或同步方法中调用
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- [转]java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- java线程同步:使用Object的wait,notify,notifyAll做线程调度
- java线程同步:使用Object的wait,notify,notifyAll做线程调度
- java Object 对象的的wait()、notify()、notifyAll()介绍
- Thread的join()方法和Object的wait(),notify(),notifyAll()方法
- Java 同步(Synchronization),等待(wait)通知(notify, notifyall)
- Object中的wait,notify,notifyAll基本使用
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理
- Java 并发编程 一 Object的wait(),notify(),notifyAll()
- Object的wait、notify、notifyall方法解析
- 【Java基础之Object类(二)、线程同步(一)】Java中使用Object类的wait,notify,notifyAll做线程调度
- 为什么wait, notify 和 notifyAll这些方法不在thread类里面?
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()的使用