我收到了以下代码段:
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将永远等待。
我不确定代码的任何其他潜在问题。
解决问题的一种可能方法是,例如在thread1
中public class ThreadTest {
private static boolean updated = false; private static boolean finished = false;
private static Thread01扩展了Thread {
public void Run(){ //做计算 而(成品){ 等待(); } //输出结果 } }
private static Thread02扩展Thread { public void run(){
而(假){ 等待(); }
foo = th1.foo; //做计算 //通知线程1的类似机制 } }
答案 0 :(得分:4)
无法保证您的帖子中有订单。 Thread01过去就足够了
{02}在Thread02执行synchronized(this){this.notify();};
以使两个线程无限期地等待之前synchronized(_th1){_th1.wait();}
。
注意:您在_th1和_th2上调用wait
和notify
这一事实无关紧要。此处的线程将被视为任何其他对象。
答案 1 :(得分:2)
@Alex已经指出了wait和notify未按代码期望的顺序调用的问题(+1)。但是,由于这是一个面试问题,因此该代码还有其他一些问题:
我确定提出的问题是将你打结并解决为什么并发性被打破但是,恕我直言,那段代码是如此可怕,我甚至不会开始调试它 - 我只是扔掉它
答案 2 :(得分:0)
以下可以是更好的修复
public class ThreadTest{
private static volatile boolean updated = false;
private static volatile boolean finished = false;
private static class Thread01 extends Thread{
private Thread02 _th2;
public int foo = 0;
public void setThread2(Thread02 th2){
_th2 = th2;
}
public void Run(){
for(int i=0;i<10;i++) foo += i;
System.out.print(" thread1 calcualtion " + foo + "\n");
try{
updated = true;
synchronized(this) {this.notify();};
synchronized(_th2){
while(!finished)
_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){
while(!updated)
_th1.wait();
foo = _th1.foo;
}
for(int i=0;i<10;i++) foo +=i;
finished = true;
synchronized(this){ this.notify();}
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread01 th1 = new Thread01();
Thread02 th2 = new Thread02(th1);
th1.setThread2(th2);
try{
th1.start();
th2.start();
th1.join();
th2.join();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}