/ 我写了下面的程序给wait()和notify()。但是在转到First put()方法之后,线程不会继续前进。任何人都可以解释一下我在下面的代码中做了什么错误。 /
public class ThreadJoin {
public void buildThread() throws InterruptedException {
Adder a = new Adder("Test");
Thread t1 = new Thread(a, "First");
Thread t2 = new Thread(a, "second");
t1.start();
t2.start();
}
public static void main(String[] args) throws InterruptedException {
new ThreadJoin().buildThread();
}
}
class Adder implements Runnable {
String name;
int i;
private boolean suspendFlag = false;
public Adder(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
for(int i = 0; i < 10; i++){
put(i);
}
for(int j = 0 ; j < 10; j++){
get();
}
}
public synchronized void put(int i) {
this.i = i;
try {
while (suspendFlag) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("put: " + i+" currentThread: "+Thread.currentThread().getName());
suspendFlag = true;
notify();
}
public synchronized void get() {
System.out.println("Entering into the get method");
try {
if (!suspendFlag) {
wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("get: " + i+" currentThread: "+Thread.currentThread().getName());
suspendFlag = true;
notify();
}
}
答案 0 :(得分:2)
首先执行哪个线程(比如说First
)将执行synchronized
put
方法,锁定Adder
对象的监视器。发生这种情况时,另一个线程(second
)无法开始执行put
方法,因为它无法锁定同一Adder
对象的监视器。
因此First
看到suspendFlag
为false
,因此会跳过while
。它会supsedFlag
true
并调用notify()
。目前Adder
对象上没有线程等待,因此对notify()
的调用不执行任何操作。
当此线程结束put
方法的执行时,监视器将被释放,second
可能会获取它。如果发生这种情况,则会看到suspendFlag
为true
并进入while
块,执行wait()
。这样做,它会释放显示器。 suspendFlag
仍为true
。
执行返回First
,for
循环put
并重新调用suspendFlag
。它看到true
为while
并进入wait()
循环,并调用wait
。
现在你的两个帖子都在notify
,并且{{1}}没有任何内容。你的程序停滞不前。
答案 1 :(得分:1)
正在进行的简单视图是您有一个等待通知结构,强制执行put
和get
次呼叫。你有两个线程,每个线程在它的第一个put
之前将进行10 get
个调用,因此无法进行交替。这两个主题最终都在put
中等待另一个执行get
。
您可以将设计更改为允许多个put
来电,而不是get
,或更改驱动代码,以便一个主题执行put
个调用而另一个执行get
{{1}}调用