达内广州C++学院|c++培训|广州达内科技C++/C#培训|.NET培训|IT培训|达内广州岗顶中心 达内广州C++学院|c++培训|广州达内科技C++/C#培训|.NET培训|IT培训|达内广州岗顶中心
java程序员
 当前位置:主页 > 高端课程 > java程序员 >

Java多线程——异常记录

时间:2019-05-15  来源:未知  作者:广州达内培训

Java多线程——异常记录

摘要:本文主要介绍了Java多线程中遇到的奇怪的异常。

部分内容来自以下博客:

https://blog.csdn.net/historyasamirror/article/details/6709693

java.lang.IllegalMonitorStateException

在测试多线程通信的代码时,出现了这个异常。

代码如下:

 1 public class Demo {
 2     public static void main(String[] args) {
 3         DemoThread demoThread = new DemoThread();
 4         Thread thread1 = new Thread(demoThread);
 5         Thread thread2 = new Thread(demoThread);
 6         thread1.start();
 7         thread2.start();
 8     }
 9 }
10 
11 class DemoThread implements Runnable {
12     private Integer num = 1;
13 
14     @Override
15     public void run() {
16         while (true) {
17             synchronized (num) {
18                 num.notify();
19                 if (num <= 10) {
20                     System.out.println(Thread.currentThread().getName() + " >>> " + num++);
21                     try {
22                         num.wait();
23                     } catch (InterruptedException e) {
24                         e.printStackTrace();
25                     }
26                 }
27             }
28         }
29     }
30 }

运行结果如下:

 1 Thread-0 >>> 1
 2 Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
 3     at java.lang.Object.notify(Native Method)
 4     at com.iyao.ide.engine.task.DemoThread.run(Demo.java:22)
 5     at java.lang.Thread.run(Thread.java:745)
 6 Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
 7     at java.lang.Object.wait(Native Method)
 8     at java.lang.Object.wait(Object.java:502)
 9     at com.iyao.ide.engine.task.DemoThread.run(Demo.java:26)
10     at java.lang.Thread.run(Thread.java:745)

结果说明:

在网上查找资料,发现需要在调用wait()或者notify()之前,必须使用synchronized语义绑定住被wait/notify的对象。

可问题是,在上面的代码中,已经对num这个变量使用了synchronzied,然后才调用的num.wait()。按理不应该抛出这个异常。

真正的问题在于num这个变量是一个Integer,并且,在调用num.wait()之前,num执行了一次自增操作。

Integer型变量在执行自增的时候,其实是创建了一个新的对象。简单的说,在自增的之前和之后,num并不是同一个对象。

synchronzied(num)绑定的是旧的Integer对象,而num.wait()使用的是新的Integer对象。由于新的Integer对象并没有使用synchronzied进行同步,所以系统抛出了IllegalMonitorStateException异常。

相同的悲剧还有可能出现在num是Boolean或者String类型的时候。

一个解决方案是采用java.util.concurrent.atomic中对应的类型,比如这里就应该是AtomicInteger。采用AtomicInteger类型,可以保证对它的修改不会产生新的对象。

修改后代码如下:

 1 public class Demo {
 2     public static void main(String[] args) {
 3         DemoThread demoThread = new DemoThread();
 4         Thread thread1 = new Thread(demoThread);
 5         Thread thread2 = new Thread(demoThread);
 6         thread1.start();
 7         thread2.start();
 8     }
 9 }
10 
11 class DemoThread implements Runnable {
12     private AtomicInteger num = new AtomicInteger(1);
13 
14     @Override
15     public void run() {
16         while (true) {
17             synchronized (num) {
18                 num.notify();
19                 if (num.intValue() <= 10) {
20                     System.out.println(Thread.currentThread().getName() + " >>> " + num.getAndAdd(1));
21                     try {
22                         num.wait();
23                     } catch (InterruptedException e) {
24                         e.printStackTrace();
25                     }
26                 }
27             }
28         }
29     }
30 }

运行结果如下:

 1 Thread-0 >>> 1
 2 Thread-1 >>> 2
 3 Thread-0 >>> 3
 4 Thread-1 >>> 4
 5 Thread-0 >>> 5
 6 Thread-1 >>> 6
 7 Thread-0 >>> 7
 8 Thread-1 >>> 8
 9 Thread-0 >>> 9
10 Thread-1 >>> 10



上一篇:Spring Cloud config中,使用数据库存储配置信息
下一篇:没有了

友情链接:
  • 24岁的哈根达斯,为何被年轻人抛弃?
  • 新零售的前世今生
  • 苏宁小店,何以创造智慧新零售的奇迹?
  • 让人大打出手的星巴克猫爪杯,到底有何猫腻?
  • 从生态摄影到生态经营
  • seo优化中的关键词重要性层次划分
  • 增加新用户数量的七种裂变方法
  • 活动运营用户定位的方法都有哪些
  • 运城软件开发关于游戏测试员的工作职责
  • 运城seo培训关键词排名波动的原因分析
  • 运城java编程开发培训常见技术问题分析
  • 018.Java类加载器
  • 016.[转] 日志 接口及实现
  • 谷歌推出搜索与语音助手 “小程序”,测试邀请 6 月启动
  • 运城达内ui设计培训课程有哪些优势
  • EL_JSTL
  • 转行上培训班去当程序员就业是否可行
  • 不运营中国市场却没忘中国卖家 亚马逊推借贷服务
  • 数组介绍
  • 如何利用python编程技术学习机器学习的知识内容
  • 几百道常见Java初中级面试题
  • 京东携手三大品牌共启“聚星闪耀日”创新电商营销新生态
  • 使用Kubernetes的java-client实现Deployment的部署及更新操作
  • 死磕 java同步系列之开篇
  • 腾讯视频进入台湾,付费会员每月 42 元
  • 小程序启动图标与加载样式设计方法
  • IO字节流。
  • springBoot学习 错误记录
  • IDEA集成tomcat启动时控制台打印中文乱码
  • 向过度索权的手机APP“开刀”
  • Servlet 总结
  • java学习:0基础入行IT快速年薪30W
  • 新技术新模式加快应用 电商物流总需求连续回升
  • 性格决定面相,原来是真的?
  • 没人扶你的时候,自己站直!
  • VMware安装Linux提示此主机支持 Intel VT-x,但 Intel VT-x 处于
  • Git将本地项目同步到github
  • 进攻左脑
  • 与其在大众的边缘,不如在小众的中心
  • 渠道数字化的答案,不是数字化
  • 新员工入职时的反污染措施
  • 云原生技术的架构特点分析
  • 为什么你的营销效果很好,却依然没有盈利?
  • 运城java培训常见的线程池类型分享
  • 我国数字经济规模已达三十一万亿元 约占GDP三分之一
  • 澳门四大赌城
  • 棋牌游戏平台
  • 888真人备用网址
  • 威尼斯人线上娱乐官网
  • 365dizhi