我试了很多年才找出为什么这不起作用但却找不到答案。 我想要做的是让两个班级“互相交谈”。 基本上我希望A做某事并为B做什么(同样为B)
class ParaTest {
boolean aCanTalk;
public static void main(String[] args) {
Test t = new Test();
t.t();
}
}
class Test {
boolean aCanTalk;
Thread a;
Thread b;
void t() {
aCanTalk = true;
a = new Thread(new A(this));
b = new Thread(new B(this));
a.start();
b.start();
}
}
class A implements Runnable {
Test t;
A(Test t) {
this.t = t;
}
public void run() {
while(t.aCanTalk) {
System.out.println("I am A");
t.aCanTalk = false;
synchronized(this) {
notifyAll();
}
try {
synchronized(t.b) {
t.b.wait();
}
} catch(InterruptedException e) {};
}
}
}
class B implements Runnable {
Test t;
B(Test t) {
this.t = t;
}
public void run() {
while(!t.aCanTalk) {
System.out.println("I am B");
t.aCanTalk = true;
synchronized(this) {
notify();
}
try {
synchronized(t.a) {
t.a.wait();
}
} catch(InterruptedException e) {};
}
}
}
答案 0 :(得分:1)
您的代码还有其他问题(见下文),但您遇到的问题是,因为在进入等待之前检查了条件,如B
:
public void run() {
while(!t.aCanTalk) {
....
}
}
如果t.aCanTalk
为真,则run方法将返回,并且线程将死亡。
(我最初误读你的代码说明了以下内容:-))
那就是说,你应该重新构建代码,因为如果你使用更多的“打包”方法制作一个合适的监视器,它就不会出错,例如一个简单的rendez-vous示例:
class Test {
private boolean aCanTalk = true;
public synchronized waitA() {
while(!aCanTalk) {
wait();
}
}
public synchronized signalB() {
aCanTalk = false;
notifyAll();
}
public synchronized waitB() {
while(aCanTalk) {
wait();
}
}
public synchronized signalA() {
aCanTalk = true;
notifyAll();
}
}
并在你的线程中使用它,例如 在A:
public void run() {
while(true) {
t.waitA();
System.out.println("I am A");
t.signalB();
}
}
和B:
public void run() {
while(true) {
t.waitB();
System.out.println("I am B");
t.signalA();
}
}
(InterruptedException
为了简洁而被忽略,它应该像你在代码中那样被捕获或抛出)
答案 1 :(得分:1)
wait
,notify
或notifyAll
的任何来电都应该被包围
try / catch子句(适用于IllegalMonitorStateException
和
InterruptedException
)。join
。Boolean aCanTalk;
上同步(请注意大写B
!)。wait()
循环中的任何while
改变我们正在同步的对象的状态。notify()
,而只使用notifyAll()
(尽管在这种特殊情况下无关紧要,因为只有两个线程)。wait
和notify
引入以来,Java已经发展,今天,在大多数情况下,您不必使用其中任何一个。以下实现不使用wait
或notify
,仍然可以实现相同的执行同步:
class ParaTest {
volatile boolean aCanTalk;
public static void main(String[] args) {
Test t = new Test();
t.t();
}
}
class Test {
volatile Boolean aCanTalk;
Thread a;
Thread b;
void t() {
aCanTalk = true;
a = new Thread(new A(this));
b = new Thread(new B(this));
a.start();
b.start();
try {
a.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class A implements Runnable {
Test t;
A(Test t) {
this.t = t;
}
public void run() {
System.out.println("I am A");
synchronized(t.aCanTalk) {
System.out.println("in synchronized (A)");
t.aCanTalk = false;
}
System.out.println("finished (A)");
}
}
class B implements Runnable {
Test t;
B(Test t) {
this.t = t;
}
public void run() {
System.out.println("I am B");
synchronized(t.aCanTalk) {
System.out.println("in synchronized (B)");
t.aCanTalk = true;
}
System.out.println("finished (B)");
}
}
答案 2 :(得分:-1)
如果您想等待线程完成,请尝试“加入”。 java文档中有一个很好的例子: http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
所以,在你的情况下,如果你想在B之前调用start之前等待A完成。
a.start();
a.join();
b.start();
至少,这是我认为你在问的问题(你的问题似乎有点不清楚)。