【发布时间】:2011-09-23 20:20:16
【问题描述】:
我得到了以下代码 sn-p:
public class ThreadTest{
private static class Thread01 extends Thread{
private Thread02 _th2;
public int foo = 0;
public void setThrd02(Thread02 thrd2){
_th2 = thrd2;
}
public void run(){
try{
for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
synchronized(_th2){_th2.wait();};
System.out.print(" Foo: " + _th2.foo);
}catch(InterruptedException ie){ ie.printStackTrace();}
}
}
private static class Thread02 extends Thread{
private final Thread01 _th1;
public int foo = 0;
public Thread02(Thread01 th1){
_th1 = th1;
}
public void Run(){
try{
synchronized(_th1){_th1.wait();}
foo = _th1.foo;
for(int i=0;i<10;i++) foo += i;
synchronized(this){this.notify();};
}
catch(InterruptedException ie){ie.printStackTrace();}
}
}
public static void main(){
Thread01 th1 = new Thread01();
Thread02 th2 = new Thread02(th1);
th1.setThrd02(th2);
th1.start(); th2.start();
th1.join(); th2.join();
}
}
我认为代码的假设和相应的目的就像 th2先运行,调用_th1.wait()变为等待状态; 然后th1计算foo并唤醒th2,th1进入等待状态; Th2 从 thread1 读取 foo 并更新为 110,然后唤醒 th1 和 th2 退出。 然后th1退出。
线程可能非常危险,因为线程 1 很可能先运行,而线程 2 将永远等待。
我不确定代码是否还有其他潜在问题。
可以解决问题的一种可能方法是,例如在线程1中
公共类 ThreadTest{
私有静态布尔更新=假; 私有静态布尔完成 = false;
私有静态 Thread01 扩展 Thread{
公共无效运行(){ // 进行计算 而(完成){ 等待(); } // 输出结果 } }
私有静态 Thread02 扩展 Thread{ 公共无效运行(){
而(假){ 等待(); }
foo = th1.foo; // 进行计算 // 类似于通知线程1的机制 } }
【问题讨论】:
-
这里还有其他严重的问题吗?纠正它的最佳方法可能是什么?
-
也许你想要一个
CyclicBarrier,让线程在一个集合点相遇? -
还要注意,即使线程 2 先成功等待线程 1,然后线程 1 循环,通知线程 2,然后线程 2 将其循环添加到 sum,它仍然不会是 110 . 这是 0 到 9 的总和,而不是 0 到 10 的总和,所以总和将是 45,而不是 55,最后的总和是 90,而不是 110。
-
CyclicBarrier 在这种情况下可能有点复杂,以下是很好的解决方法:
标签: java multithreading concurrency