线程在等待问题后通知不工作-java



我找不到问题有人能帮我吗?

public class Achterbahn {
private final Object monitor = new Object();
public   synchronized void test() throws InterruptedException {


//monitor.wait();

System.out.println("car");
wait();
System.out.println("car");

}
public  synchronized void Passagier() throws InterruptedException {
Thread.sleep(2000);

System.out.println("p");
notify();

//b.t1.notify();


}
public static void main(String []args) throws InterruptedException {

Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

});
Thread t5= new Thread(new Runnable() {

@Override
public void run() {
Achterbahn b = new Achterbahn();
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}


});


new Thread(t4).start();
new Thread(t5).start();     
t5.join();
t4.join();

}

}

输出为:汽车p

它似乎是通知工作,我想打印也车在最后,但我不知道为什么它不工作

我希望有人能尽快帮我。

我在同一个类中有所有的方法,我也尝试过单独创建类,但不起作用

(我猜在这种情况下,"它不起作用"意味着程序挂起。请具体说明您看到的问题是什么。(

共有2个问题。一种是在每个线程中创建单独的对象。调用等待和通知的对象必须相同,等待的监视器是需要接收通知的监视器。在这段代码中,同步的方法在调用方法的实例上使用内部锁

在main方法中创建一次对象,每个线程都需要引用同一个对象。

第二个问题,一旦你解决了第一个问题,将是一个比赛条件。如果一个线程执行的通知首先发生,那么当等待执行时,通知已经发生,等待将永远等待。

添加一个条件变量以记住是否发生了通知。

一般情况下,模式是在循环中检查条件,请参阅以下问题:为什么我们必须使用";而";用于检查比赛条件不是"0";如果";。这篇文章有一个使用变量查看条件是否发生的例子,这里是

synchronized(obj)
{
while (condition_not_matched)
{
obj.wait();
}
//continue
dosomething();
}

你做错了几件事。

  • 只启动一个C实例。然后使用该实例来调用您的方法。不同的实例在同步方法中不共享监视器
  • 当您启动两个新线程时,您正在启动它们。只需按以下方式启动它们:
t4.start();
t5.start();

主要问题是t4首先启动并立即休眠。所以t5在睡眠结束之前不会启动。但到那时,在t5中调用wait()之前,t4中等待的notify()已经发出了。因此,wait永远不会看到它。因此,您需要在睡眠发生之前给t4一个启动的机会。有几种方法可以解决这个问题。一种是使用一个标志来表示另一种方法已经准备好了。但不要使用紧while循环。在里面放一个sleep一小段时间。我在下面提供了一个例子。我还为您的线程分配了名称,以匹配您的变量。


public class C {
boolean ready = false;

public synchronized void test() throws InterruptedException {
System.out.println("Current thread = " + Thread.currentThread().getName());     
ready = true;
System.out.println("car");
wait();
System.out.println("car");
}

public synchronized void Passagier() throws InterruptedException {
Thread.sleep(4000);
System.out.println("Current thread = " + Thread.currentThread().getName());
System.out.println("p");
notify();

}

public static void main(String[] args)
throws InterruptedException {
C b = new C();
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
while(!b.ready) {
Thread.sleep(100);
}
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},"t4");

Thread t5 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

},"t5");
System.out.println("Starting t4");
t4.start();
System.out.println("Starting t5");
t5.start();
//      
t5.join();
t4.join();

}

}

这个代码对我有效我现在有while循环

public class C {
int i = 34;
public synchronized void test() throws InterruptedException {
System.out.println("car");
while(i == 34) {
wait();
}

notify();
System.out.println("car");
}
public synchronized void Passagier() throws InterruptedException {
i = 55;
System.out.println("p");

notify();

}
public static void main(String[] args)
throws InterruptedException {

C b = new C();
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
b.Passagier();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread t5 = new Thread(new Runnable() {

@Override
public void run() {
try {
b.test();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

});



t4.start();
t5.start();
t4.join();
t5.join();
}
}

最新更新