我得到了以下代码片段:
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中
公共类ThreadTest{
私有静态布尔更新= false;私有静态布尔完成= false;
私有静态Thread01扩展了线程{
public void Run(){ //执行calcuation (已完成){ wait();} //输出结果}}
私有静态运行扩展了线程{ public void Thread02 (){
while(false){ wait();}
foo = th1.foo;//进行计算//类似机制通知线程1}}
发布于 2011-06-28 05:23:54
你的线程没有排序的保证。对于Thread01来说,在Thread02执行synchronized(_th1){_th1.wait();}之前通过synchronized(this){this.notify();};就足以让两个线程都无限期地等待。
注意:您在_th1和_th2上调用wait和notify这一事实是无关紧要的。这里的线程将被视为任何其他对象。
发布于 2011-06-28 07:01:33
@Alex已经指出了等待和通知没有按照代码期望的顺序调用(+1)的问题。然而,由于这是一个面试问题,所以这段代码还存在其他几个问题:
<代码>H19无异常处理、<代码>H210<代码>H111(个人偏好)不使用Java并发库。<代码>H212<代码>G213
我相信这个问题的提出是为了让你感到困惑,并弄清楚为什么并发被破坏了,但是,我想,这些代码是如此丑陋,我甚至不会开始调试它--我只是把它扔掉了。
发布于 2011-06-28 07:05:42
下面是一个更好的修复方法
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();
}
}https://stackoverflow.com/questions/6498982
复制相似问题