一段代码分析 理解多线程交互
来源:互联网 发布:mac 终端 ip地址 编辑:程序博客网 时间:2024/06/05 06:17
将notifyAll()移到synchronized代码块里面既可以解决异常
* 计算线程
*/
public class Calculator extends Thread {
int total;
public void run() {
synchronized (this) {
for (int i = 0; i < 101;i++) {
total+= i;
}
}
//通知所有在此对象上等待的线程
notifyAll();
}
}
/**
* 获取计算结果并输出
*
* @author leizhimin 2008-9-20 11:15:22
*/
class ReaderResult extends Thread {
Calculator c;
public ReaderResult(Calculator c) {
this.c = c;
}
public void run() {
synchronized (c) {
try {
System.out.println(Thread.currentThread()+ "等待计算结果。。。");
c.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread()+ "计算结果为:" + c.total);
}
}
public static void main(String[] args) {
Calculatorcalculator = new Calculator();
//启动三个线程,分别获取计算结果
newReaderResult(calculator).start();
newReaderResult(calculator).start();
newReaderResult(calculator).start();
//启动计算线程
calculator.start();
}
}
运行结果:
Thread[Thread-1,5,main]等待计算结果。。。
Thread[Thread-2,5,main]等待计算结果。。。
Thread[Thread-3,5,main]等待计算结果。。。
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current threadnot owner
at java.lang.Object.notifyAll(Native Method)
at threadtest.Calculator.run(Calculator.java:18)
Thread[Thread-1,5,main]计算结果为:5050
Thread[Thread-2,5,main]计算结果为:5050
Thread[Thread-3,5,main]计算结果为:5050
Process finished with exit code 0
运行结果表明,程序中有异常,并且多次运行结果可能有多种输出结果。这就是说明,这个多线程的交互程序还存在问题。究竟是出了什么问题,需要深入的分析和思考,下面将做具体分析。
实际上,上面这个代码中,我们期望的是读取结果的线程在计算线程调用notifyAll()之前等待即可。但是,如果计算线程先执行,并在读取结果线程等待之前调用了notify()方法,那么又会发生什么呢?这种情况是可能发生的。因为无法保证线程的不同部分将按照什么顺序来执行。幸运的是当读取线程运行时,它只能马上进入等待状态----它没有做任何事情来检查等待的事件是否已经发生。 ----因此,如果计算线程已经调用了notifyAll()方法,那么它就不会再次调用notifyAll(),----并且等待的读取线程将永远保持等待。这当然是开发者所不愿意看到的问题。
因此,当等待的事件发生时,需要能够检查notifyAll()通知事件是否已经发生。
通常,解决上面问题的最佳方式是利用某种循环,该循环检查某个条件表达式,只有当正在等待的事情还没有发生的情况下,它才继续等待。
- 一段代码分析 理解多线程交互
- 多线程程序一段问题代码分析
- 一段代码深入分析
- 一段javascript代码分析
- JAVA多线程的一段代码
- 一段理解nio的代码
- 一段代码理解函数指针
- C# 一段代码理解”委托“
- 一段绕过JDBC的数据库交互代码
- 谁能帮我分析一段代码?
- 一段经典C代码分析
- 一段流量分析工具代码
- 一段重入锁的代码分析
- 一段反 ASM 代码分析。。
- 一段汇编代码的分析
- SVNKIT一段代码的分析
- 对一段有趣代码分析
- 分析一段代码理解main函数与子线程间的关系
- (转)C++中extern “C”含义深层探索
- debian和ubuntu下apache2重定向模块的添加
- 乔布斯的帝国
- MySQL入门很简单-学习笔记 - 第 8 章 视图
- PHP--isset()和unset()函数的用法
- 一段代码分析 理解多线程交互
- test
- 传雅虎曾拒马云35亿美元回购阿里15%股权提议
- 数据库各阶段下能执行的操作
- linux平台下防火墙iptables原理及用法简介
- 【android应用】——设置控件的透明度
- Flex 自定义带有收缩功能的Panel组件
- win7,windowsXP安装mysql-5.1.49-win32
- string