这个java程序,为什么一个notify唤醒了3个wait
2017-04-13 10:34
661 查看
1、
结果:
1
2
3
lock open
一
三
二
答案:
原因是共用的对象本身也是一个线程,所以notify的时候,如果被唤醒的是Go1的线程,那么Go2和Go3中的g.wait();也会跟着返回,所以相当于Go1,Go2,Go3都被唤醒,然后一起争夺锁。把共用的对象换成一个普通的对象就没有问题了。代码如下:
结果:
1
2
3
lock open
一
来源:javaeye问答
http://www.iteye.com/problems/89570
public class Demo6 { public static void main(String[] args) { Go1 q = new Go1(); Go2 qq = new Go2(q); Go3 qqq = new Go3(q); Come w = new Come(q); q.start(); qq.start(); qqq.start(); w.start(); } } // 线程1,打印1,等待,唤醒后打印一 class Go1 extends Thread { public void run() { synchronized (this) { System.out.println("1"); try { wait(); } catch (Exception e) { } } System.out.println("一"); } } // 线程2,打印2,等待,唤醒后打印二 class Go2 extends Thread { Go1 g; Go2(Go1 g) { this.g = g; } public void run() { synchronized (g) { System.out.println("2"); try { g.wait(); } catch (Exception e) { } } System.out.println("二"); } } // 线程3,打印3,等待,唤醒后打印三 class Go3 extends Thread { Go1 g; Go3(Go1 g) { this.g = g; } public void run() { synchronized (g) { System.out.println("3"); try { g.wait(); } catch (Exception e) { } } System.out.println("三"); } } // 唤醒线程 class Come extends Thread { Go1 r; Come(Go1 r) { this.r = r; } public void run() { try { sleep(100); } catch (Exception e) { } synchronized (r) { r.notify(); System.out.println("lock open"); } } }
结果:
1
2
3
lock open
一
三
二
答案:
原因是共用的对象本身也是一个线程,所以notify的时候,如果被唤醒的是Go1的线程,那么Go2和Go3中的g.wait();也会跟着返回,所以相当于Go1,Go2,Go3都被唤醒,然后一起争夺锁。把共用的对象换成一个普通的对象就没有问题了。代码如下:
public class Demo7 { public static void main(String[] args) { Go g = new Go(); Go1 q = new Go1(g); Go2 qq = new Go2(g); Go3 qqq = new Go3(g); Come w = new Come(g); q.start(); qq.start(); qqq.start(); w.start(); } } class Go { } class Go1 extends Thread { Go g; Go1(Go g) { this.g = g; } public void run() { synchronized (g) { System.out.println("1"); try { g.wait(); } catch (Exception e) { } } System.out.println("一"); } } class Go2 extends Thread { Go g; Go2(Go g) { this.g = g; } public void run() { synchronized (g) { System.out.println("2"); try { g.wait(); } catch (Exception e) { } } System.out.println("二"); } } class Go3 extends Thread { Go g; Go3(Go g) { this.g = g; } public void run() { synchronized (g) { System.out.println("3"); try { g.wait(); } catch (Exception e) { } } System.out.println("三"); } } class Come extends Thread { Go r; Come(Go r) { this.r = r; } public void run() { try { sleep(100); } catch (Exception e) { } synchronized (r) { r.notify(); System.out.println("lock open"); } } }
结果:
1
2
3
lock open
一
来源:javaeye问答
http://www.iteye.com/problems/89570
相关文章推荐
- 为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失
- 一个最简单的java程序,没有任何import 为什么还能System.out.println
- JAVA 线程等待唤醒,wait and notify
- 一个关于Java Thread wait(),notify()的实用例
- 为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失
- 为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失
- 一个关于Java Thread wait(),notify()的实用例
- Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期
- 2. 编写一个Java应用程序,用户从键盘输入一个1~9999之间的数,程序将判断这个数是几位数,并判断这个数是否是回文数。回文数是指将该数含有的数字逆序排列后得到的数和原数相同,例如12121、32
- 通过这个例子一眼就看懂java中wait和notify()用法
- java线程同步问题(一个理解wait()与notify()的例子)
- Java 为什么使用wait()/notify()机制?
- Java第七课 Java的多线程程序进程和线程的概念,实现多线程的两种方式,线程同步的原理,线程的死锁,运用wait和notify来实现producer - consumer关系,线程终止的两种情况。
- Java多线程---------同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期
- 为什么Java的每个对象都有wait()/notify()方法?
- 为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失
- java 线程wait()与notify()的用法(被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行)
- 一个关于Java Thread wait(),notify()的实用例
- 【程序9】 WanShu.java 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。
- 为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失