线程之间通讯--java.lang.IllegalMonitorStateException
来源:互联网 发布:python time 精确到秒 编辑:程序博客网 时间:2024/06/04 00:26
在写多线程之间通讯的例子--生产者跟消费者时,我用到了wait跟notify,结果在运行时报了java.lang.IllegalMonitorStateException异常,查了一下,这个异常叫做违法的监控状态异常。官方的解释是当一个线程试图等待一个自己并不拥有的对象的监控器或者通知其他线程等待该对象的监控器时抛出的异常。这个解释有点绕,我用代码来说明:以下是出错的代码
public class ThreadCommunicate {public static void main(String[] args) {Res res = new Res();InputThread input = new InputThread(res);OutThread out = new OutThread(res);input.start();out.start();}}class Res {public String name;public String sex;public boolean flag;//flag为true,表示已经生产了,还没有消费}class InputThread extends Thread{private Res res;public int count = 0;public InputThread(Res res) {this.res = res;}@Overridepublic void run() {while(true){if(res.flag){try {res.wait();} catch (InterruptedException e) {e.printStackTrace();}}if(count == 0){res.name = "小红";res.sex = "女";} else {res.name = "boss";res.sex = "男";}count = (count + 1)%2;res.flag = true;res.notify();}}}class OutThread extends Thread{private Res res;public OutThread(Res res) {this.res = res;}@Overridepublic void run() {while(true){if(!res.flag){try {res.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(res.name + ":" + res.sex);res.flag = false;res.notify();}}}
这段代码有两个线程input与out同时操作同一个对象res,存在线程同步问题,但我并没有解决这个问题,同时我使用了wait跟notify,在线程不同步的时候,就会出现input线程在执行完res.notify()之后,进入到if判断之后、执行res.wait()之前就交出了cpu时间片给out执行,out执行完res.notify()之后进入if中执行res.wait()等待,之后交出cpu时间片给input,然后input也执行了res.wait(),产生了官方所描述的冲突。当然究其主要原因还是因为我没有解决这两个线程的同步问题,以下是改进后的方案:
public class ThreadCommunicate {public static void main(String[] args) {Res res = new Res();InputThread input = new InputThread(res);OutThread out = new OutThread(res);input.start();out.start();}}class Res {public String name;public String sex;public boolean flag;//flag为true,表示已经生产了,还没有消费}class InputThread extends Thread{private Res res;public int count = 0;public InputThread(Res res) {this.res = res;}@Overridepublic void run() {while(true){synchronized (res) {if(res.flag){try {res.wait();} catch (InterruptedException e) {e.printStackTrace();}}if(count == 0){res.name = "小红";res.sex = "女";} else {res.name = "boss";res.sex = "男";}count = (count + 1)%2;res.flag = true;res.notify();}}}}class OutThread extends Thread{private Res res;public OutThread(Res res) {this.res = res;}@Overridepublic void run() {while(true){synchronized (res) {if(!res.flag){try {res.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(res.name + ":" + res.sex);res.flag = false;res.notify();}}}}
总结:
wait与notify在使用的时候必须要保证线程同步。
以上是个人见解,如有不足之处,希望各位指正,谢谢!
阅读全文
0 0
- 线程之间通讯--java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException翻译
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- 处理java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException异常
- 关于java.lang.IllegalMonitorStateException
- 关于java.lang.IllegalMonitorStateException
- 关于java.lang.IllegalMonitorStateException
- 关于java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- java.lang.IllegalMonitorStateException
- CSS表格
- 学习历程->Oracle流程控制及存储过程
- iframe内嵌高德地图搜索
- 快速掌握 MongoDB 数据库
- Entity Framework Core 使用体会
- 线程之间通讯--java.lang.IllegalMonitorStateException
- 171207之JSON和XML
- sublime text3注册码
- json对象中的方法
- BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】
- eclipse上正确运行tomcat项目的方法
- ES6学习之路6----箭头函数
- 融资2.1亿商汤领投,他要用VR+AR解决无人驾驶的路测难题
- shell脚本常用语句用法笔记