您的位置:首页 > 编程语言 > Java开发

这个java程序,为什么一个notify唤醒了3个wait

2017-04-13 10:34 661 查看
1、

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
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐