有关Java线程wait后唤醒的问题

gcsdn2000 2013-04-23 08:22:43
一般来说,wait后要通过notify来唤醒,但是最近看书写的一个小程序,没有notify也唤醒了,不知道什么原因,还望论坛里的大神赐教。


源代码如下:

package edu.cczu.mythread1;

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JProgressBar;

public class Commnicate extends JFrame{

Thread t1;
Thread t2;
private int count=0;
final JProgressBar progressBar = new JProgressBar();
public static void main(String[] args) {
init(new Commnicate(),150,100);

}
public Commnicate() {
super();
progressBar.setStringPainted(true);
getContentPane().add(progressBar, BorderLayout.NORTH);
deValue();
addValue();
t1.start();
t2.start();
}
public void addValue(){
t1=new Thread(new Runnable(){
public void run(){
try{
Thread.currentThread().sleep(10000);
System.out.println("线程退出");
}catch(Exception e){
e.printStackTrace();
}
}
});
}
public void deValue(){
t2=new Thread(new Runnable(){
public void run(){
while (true) {
if(count==0){
synchronized (t1) {
try {
System.out.println("t2等待");
t1.wait(); //这里应该等待,为什么t1结束后就被唤醒了?
System.out.println("t2等待结束");
count = 10;
} catch (Exception e) {
e.printStackTrace();
}
}
}
progressBar.setValue(--count);
System.out.println("进度条的当前值为:" + count);
}
}
});
}
public static void init(JFrame frame,int width,int height){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width, height);
frame.setVisible(true);
}
}

t1.wait(); //这里应该等待,为什么t1结束后就被唤醒了?
当然只是执行了一次,第二次就停在那儿了。
...全文
268 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lcf 2013-04-24
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/390352356 正解。不过观察下面的代码:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JProgressBar;

public class Communicate extends JFrame {

  Thread t1;
  Thread t2;
  private int count = 0;
  final JProgressBar progressBar = new JProgressBar();

  public static void main(String[] args) throws InterruptedException {
    init(new Communicate(), 150, 100);

  }

  public Communicate() throws InterruptedException {
    super();
    progressBar.setStringPainted(true);
    getContentPane().add(progressBar, BorderLayout.NORTH);
    deValue();
    addValue();
    t1.start();
    synchronized (t1) {
      Thread.currentThread().sleep(1000);
      t1.wait();
    }
    t2.start();
  }

  public void addValue() {
    t1 = new Thread(new Runnable() {
      public void run() {
        try {
          System.out.println("线程退出");
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  public void deValue() {
    t2 = new Thread(new Runnable() {
      public void run() {
        while (true) {
          if (count == 0) {
            synchronized (t1) {
              try {
                System.out.println("t2等待");
                t1.wait(); //这里应该等待,为什么t1结束后就被唤醒了?
                System.out.println("t2等待结束");
                count = 10;
              }
              catch (Exception e) {
                e.printStackTrace();
              }
            }
          }
          progressBar.setValue(--count);
          System.out.println("进度条的当前值为:" + count);
        }
      }
    });
  }

  public static void init(JFrame frame, int width, int height) {
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(width, height);
    frame.setVisible(true);
  }
}
输出的是: 线程退出 t2等待 请问为什么? 解释稍后回复。这是一个很好的面试题哦
u010431717 2013-04-24
  • 打赏
  • 举报
回复
henhao
  • 打赏
  • 举报
回复
调用wait应该是当前对象调用。
nmyangym 2013-04-24
  • 打赏
  • 举报
回复
楼主可以参考以下: http://bbs.csdn.net/topics/390352356
lcf 2013-04-24
  • 打赏
  • 举报
回复
呃,已经结贴了么,那就算了。。
gcsdn2000 2013-04-24
  • 打赏
  • 举报
回复
3楼的是正解,另外看了3楼写的博文,弄明白了这个问题,谢谢!
lcf 2013-04-23
  • 打赏
  • 举报
回复
好像是thread的终结让Thread这个对象本身的wait()方法失效了。如果你把Sleep(10000)移到t1.start()后面,然后加上t1.wait(),自然要用synchronized包住这三句话,你会发现main线程是不会进入BLOCKED状态的。具体为啥还是要请高手来解答了。不过就楼主这个应用,不应该用t1直接当做锁,新建一个Object,然后用它来当锁才是正解
u010232646 2013-04-23
  • 打赏
  • 举报
回复
wait()方法不是thread的方法,它是object这个类的方法,它的监听对象是调用方法的这个类,所以你的方法用错了。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧