Java中多线程关于wait()和notify()方法的小错误备忘录
来源:互联网 发布:哈尔滨资海网络怎么样 编辑:程序博客网 时间:2024/06/06 03:54
最近在学习Java多线程中,遇到了一个问题,代码如下:
class Obj {//交替打印张三与李四的文字 public static int flag = 0; public String name; Obj(String name) {this.name = name; } public synchronized void print() {System.out.print(name + "::");System.out.println("打印一段文字"); }}
public class ExceptionInWait { public static void main(String[] args) {Obj o1 = new Obj("张三");Obj o2 = new Obj("李四");Thread t1 = new Thread() {@Overridepublic void run() {int flag = 1;while (true) {if (flag == Obj.flag) {o1.print();<span style="white-space:pre"></span>Obj.flag = 0;<span style="white-space:pre"></span>o1.notifyAll(); // 错误1<span style="white-space:pre"></span> } else {<span style="white-space:pre"></span>try {<span style="white-space:pre"></span> o1.wait(); // 错误2<span style="white-space:pre"></span>} catch (InterruptedException e) {<span style="white-space:pre"></span> e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span> }<span style="white-space:pre"></span>}<span style="white-space:pre"></span> }<span style="white-space:pre"></span>};<span style="white-space:pre"></span>Thread t2 = new Thread() {<span style="white-space:pre"></span> @Override<span style="white-space:pre"></span> public void run() {<span style="white-space:pre"></span>int flag = 0;<span style="white-space:pre"></span>while (true) {<span style="white-space:pre"></span> if (flag == Obj.flag) {<span style="white-space:pre"></span>o2.print();<span style="white-space:pre"></span>Obj.flag = 1;<span style="white-space:pre"></span>o1.notifyAll(); // 错误3<span style="white-space:pre"></span> } else {<span style="white-space:pre"></span>try {<span style="white-space:pre"></span> o2.wait();// 错误4<span style="white-space:pre"></span>} catch (InterruptedException e) {<span style="white-space:pre"></span> e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span> }<span style="white-space:pre"></span>}<span style="white-space:pre"></span> }<span style="white-space:pre"></span>};<span style="white-space:pre"></span>t1.start();<span style="white-space:pre"></span>t2.start(); }}
出现错误的地方我标明了,作为一个java新手,之前很不理解为什么会导致这样的错误。在仔细阅读了Oracle官方教程中的Concurrency这一章之后,才有所领悟
When a thread invokes d.wait, it must own the intrinsic lock for d
然而在对象中,因为print方法持有synchronized关键字,于是执行完后,已经都把各自的锁给释放掉了
使用wait和notify方法之前,一定要确认当前线程持有的锁对象,如果锁对象不存在,就会发生IllegalMonitorStateException;如果锁对象存在,但是没有像预期一样设置好,程序的运行结果会与预期不同
原文链接:http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
第一次用编辑器,懒得去纠正错误代码的格式了,下面贴上正确的代码
public class ExceptionInWait { public static void main(String[] args) {Obj o1 = new Obj("张三", 0);Obj o2 = new Obj("李四", 1);final Object lock = new Object();o1.setLock(lock);o2.setLock(lock);Thread t1 = new Thread() { @Override public void run() {while (true) { o1.print();} }};t1.setName("张三的线程");Thread t2 = new Thread() { @Override public void run() {while (true) { o2.print();} }};t2.setName("李四的线程");t1.start();t2.start(); }}class Obj { public static int flag = 0; public int targetFlag; public String name; private Object lock; public void setLock(Object lock) {this.lock = lock; } Obj(String name, int targetFlag) {this.name = name;this.targetFlag = targetFlag; } public void print() {synchronized (lock) { if (targetFlag == flag) {System.out.print(name + "::");System.out.println("打印一段文字");//Alter the conditionif(Obj.flag==1){ Obj.flag=0;}else{ Obj.flag=1;}lock.notifyAll();//线程通讯一定要使用正确的锁对象;wait和notify方法的前提是该线程持有锁对象! }else{try { lock.wait();} catch (InterruptedException e) { e.printStackTrace();} }} }}
0 0
- Java中多线程关于wait()和notify()方法的小错误备忘录
- Java多线程中wait()和notify()
- JAVA多线程中synchronized,wait和notify的关系
- Java多线程中wait和notify的异同
- 初识java多线程的wait(), notify()方法
- Java多线程的wait()和notify()例子
- Java多线程的wait()和notify()例子
- Java多线程wait()和notify()
- java的wait和notify方法浅析
- 关于 JAVA wait()和notify()
- java 关于wait 和notify
- java多线程中wait()和notify()和notifyAll()及其他常用方法使用
- Java中wait,notify方法
- JAVA多线程编程:wait() 和 notify() 方法示例
- 浅析Java多线程synchronized关键字、wait和notify方法
- Java多线程wait()、notify()小demo
- 关于Java多线程中的wait()、sleep()、notify()和notifyAll()的简单介绍和使用
- Java多线程编程——关于notify(), wait()的问题
- 重写highlighted改变按钮的按下状态、
- iOS 开发之动画篇 - 从 UIView 动画说起
- 时间日期函数——小智慧大舞台
- 常见浏览器的兼容问题
- android性能优化
- Java中多线程关于wait()和notify()方法的小错误备忘录
- Make Menuconfig详解 (配置内核选择)
- <自用>plsql破解方法
- XMPP协议
- 开发工具
- LinuxC高级编程——进程
- 每天laravel-20160623|NullStore
- FMDB官方使用文档 G-C-D的使用
- MYSQL批量插入数据库实现语句性能分析