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

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

 

你可能感兴趣的:(notify)