public class ReaderResult extends Thread {
Calculator c; public ReaderResult(Calculator c) {
this.c = c;
} public void run() {
synchronized (c) {
try {
System.out.println(Thread.currentThread() + "等待计算结果");
c.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "计算结果为:" + c.total);
}
} public static void main(String[] args) {
Calculator calculator = new Calculator();
//启动三个线程,分别获取计算结果
new ReaderResult(calculator).start();
new ReaderResult(calculator).start();
new ReaderResult(calculator).start();
//启动计算线程
calculator.start();
}
}
public class Calculator extends Thread {
int total;
public void run() {
synchronized (this) {
System.out.println(total);
for (int i = 0; i < 101; i++) {
total += i;
}
System.out.println(total);
}
}
}
就2个简单的类 , 以我的认识,应该在c.wait()这里卡住,也就是说应该不会输出“计算结果为:" ”这些话。 但是为什么他有时候会输出呢?(有时候不会)。 到底是什么破坏了wait 状态? 应该不是start, 因为有时候是先输出System.out.println(total)这里, 然后再打印等待计算结果。。 高人请指点下
多线程javathread
2、没有notify的激活,照理说,是阻塞在wait这里的。
因为c.wait()会在c这个线程结束后,退出等待。
(上面的 对象c在main里是叫 calculator).
所以,楼主的代码如果如果calculator这个先结束,后运行的c.wait(),则程序就会一直停那;否则先运行c.wait(),calculator后结束,wait状态会在calculator结束后唤醒。我曾经写过一篇博客,楼主参考一下。
http://blog.csdn.net/nmyangym/article/details/7850882
楼主也可以看看jion()方法的原代码。
结果没搜到什么有价值的东西……我这么搜的原因是:
如果你把你的 Calculator 实现改一改, 改成 implements Runnable 的话,你就会发现正常了。
不过话说回来,wait notify 可以被认为是过时的机制,自从concurrent包之后,不要再用 wait notify 了,所以研究的意义可能也不大……要一个线程去等另一个线程,或者等某一个条件达成,concurrent包里有不好工具可以用,方法也不止一种(看情况用哪种),每一种都比 wait notify 好。
public class ReaderResult extends Thread {
Calculator c;
public ReaderResult(Calculator c) {
this.c = c;
} public void run() {
synchronized (this) {
try {
System.out.println(Thread.currentThread() + "等待计算结果");
this.wait();
} catch (Exception e) {
e.printStackTrace();
}
c.start();
System.out.println(Thread.currentThread() + "计算结果为:" + c.total);
}
} public static void main(String[] args) {
Calculator calculator = new Calculator();
Calculator calculator1 = new Calculator();
Calculator calculator2 = new Calculator();
// 启动三个线程,分别获取计算结果
new ReaderResult(calculator).start();
new ReaderResult(calculator1).start();
new ReaderResult(calculator2).start();
// 启动计算线程 }
}
1、Calculator线程在执行run()函数结束后,会调用exit()方法;该方法执行完毕之后会发出一个notifyAll(),但没有找到对应代码,可能是在native代码中完成的;
2、楼主所说“有时候是先输出System.out.println(total)这里, 然后再打印等待计算结果”
是因为有的线程启动慢了(可以用循环来批量new ReaderResult(calculator).start(),比如100个,就会更明显);然后没有及时进入 synchronized (c) { 代码块,直到Calculator执行完毕才抢到c的独占权,所以最终卡在c.wait()而再也没机会唤醒了。