日期:2014-05-20  浏览次数:20938 次

Java 线程不能notify
写了一个非常简单的 wait 和notify的例子,本来应该在中途 唤醒  wait()一次,实际却没有。
测试类:
public class Test1 {
public static int[] a = {0};
public static void main(String[] args) {
Wait1 w = new Wait1();
Notify1 n = new Notify1();
w.start();
n.start();
}
}
notify 类
public class Notify1 extends Thread{
public void run(){
synchronized(Test1.a){
for(int i = 0;i<10;i++){
Test1.a[0] += 1;
try{
Thread.sleep(1000);
}catch(Exception e){
}
                                // i=5的时候唤醒一次
if(i == 5){
Test1.a.notifyAll();
try{
Thread.sleep(1000);
}catch(Exception e){
}
}
System.out.println("Notify :"+Test1.a[0]);
}
}
}
}
wait 类
public class Wait1 extends Thread{
public void run(){
synchronized(Test1.a){
System.out.println("I am waiting !");
try{
Test1.a.wait();
}catch(Exception e){
}
Test1.a[0]+=100;
System.out.println("Wait1  :"+Test1.a[0]);
}
}
}
测试结果
I am waiting !
Notify :1
Notify :2
Notify :3
Notify :4
Notify :5
Notify :6
Notify :7
Notify :8
Notify :9
Notify :10
Wait1  :110
求大神帮看看原因~~~~~~
------解决方案--------------------
引用:
Quote: 引用:

写了一个非常简单的 wait 和notify的例子,本来应该在中途 唤醒  wait()一次,实际却没有。
测试类:
public class Test1 {
public static int[] a = {0};
public static void main(String[] args) {
Wait1 w = new Wait1();
Notify1 n = new Notify1();
w.start();
n.start();
}
}
notify 类
public class Notify1 extends Thread{
public void run(){
synchronized(Test1.a){
for(int i = 0;i<10;i++){
Test1.a[0] += 1;
try{
Thread.sleep(1000);
}catch(Exception e){
}
                                // i=5的时候唤醒一次
if(i == 5){
Test1.a.notifyAll();
try{
Thread.sleep(1000);
}catch(Exception e){
}
}
System.out.println("Notify :"+Test1.a[0]);
}
}
}
}
wait 类
public class Wait1 extends Thread{
public void run(){
synchronized(Test1.a){
System.out.println("I am waiting !");
try{
Test1.a.wait();
}catch(Exception e){
}
Test1.a[0]+=100;
System.out.println("Wait1  :"+Test1.a[0]);
}
}
}
测试结果
I am waiting !
Notify :1
Notify :2
Notify :3
Notify :4
Notify :5
Notify :6
Notify :7
Notify :8
Notify :9
Notify :10
Wait1  :110
求大神帮看看原因~~~~~~

你问题是在Notify1 中notifyAll后,调用Thread.sleep()不会释放Test1.a的锁,Wait1 获取不到Test1.a的锁,就只能等Notify1运行完了;

然后这样该下测试下:
Notify1 :
if(i == 5){
Test1.a.notifyAll();
try{
Test1.a.wait();
}catch(Exception e){
}

Wait1 :
if(Test1.a[0] == 9){
Test1.a.notifyAll();
}
------解决方案--------------------
Wait1先持有Test1.a的锁,当执行Test1.a.wait()后,Wait1将Test1.a的锁释放,并等待别的线程执行Test1.a.notifyAll(),才能被唤醒。
此时,Notify1获得Test1.a的锁,开始执行,当for循环到i=5时,虽然执行Test1.a.notifyAll()可以唤醒Wait1,但是Wait1必须得获得Test1.a的锁才能执行,而Notify1并未释放锁(注意执行Thread.sleep(1000);,并不释放锁),所以Wait1等待执行。当Notify1执行结束,释放锁,然后Wait1获得锁,执行。。。
修改后的Notify1
public class Notify1 extends Thread {
public void run() {
synchronized (Test1.a) {
for (int i = 0; i < 10; i++) {
Test1.a[0] += 1;
try {
Thread.sleep(1000);
} catch (Exception e) {
}
// i=5的时候唤醒一次
if (i == 5) {
 Test1.a.notifyAll();
 //添加wait
 try {
Test1.a.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//删掉sleep
 /*try {
Thread.sleep(1000);
} catch (Exception e) {
}*/
}
System.out.println("Notify :" + Test1.a[0]);
}
}
}
}

Wait1
public class Wait1 extends Thread {