java如果我有一个可运行线程和一个实现线程,如何使用wait()和notify()?
我想在第一个线程完成后开始第二个线程。但是,如果线程的实现方式不同,我不知道如何使用wait()/notify()函数。 第一次尝试在单独的类中使用它,但之后我无法让第一个线程在完成时发出信号
public class Oblig1 {
static void threadMessage(String message) {
String threadName =
Thread.currentThread().getName();
System.out.format("%s: %s%n",
threadName,
message);
}
private boolean start = false;
public void StartThread(){
start = true;
}
class Thread1 implements Runnable{
private int X;
Thread2 obj = new Thread2(5);
public Thread1(int x) {
X = x;
}
public synchronized void run() {
for (int i=1; i<21; i++) {
System.out.print(X*i + " ");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
StartThread();
notifyAll();
}
}
class Thread2 extends Thread {
private int X;
public Thread2(int x) {
X = x;
}
public synchronized void run() {
while (!start){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (int i=1; i<21; i++) {
System.out.print(X*i + " ");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
notifyAll();
}
}
public static void main(String [ ] args) {
int inputT1 = 3;
int inputT2 = 5;
Thread t1 = new Thread(new Thread1(inputT1));
Thread t2 = new Thread(new Thread2(inputT2));
t1.start();
t2.start();
}
}
# 1 楼答案
您等待某个对象并通知某个对象(在当前代码中,您没有指定对象,所以它是
this
)。因此,线程本身调用notify,但没有人在等待它。Thread2正在等待自己,但没有人唤醒它(因为没有人在Thread2的这个实例上调用notify)要唤醒Thread2,需要在该对象上调用notify(这是this),这样Thread1就应该调用obj。notify()(因为在代码中obj是Thread2)
但是,它仍然无法工作,因为您没有将Thread2实例传递给Thread1(您只是在Thread1中创建了一个新实例),所以您通知的Thread2刚刚创建,从未启动。主线程中的线程2已启动,但从未收到通知
对代码的可能修复
# 2 楼答案
wait()
和notify()
方法是低级原语,最好避免使用高级并发API。滚动自己的并发代码可能会有问题(例如,代码中的start
字段需要易变!)一个简单的解决方法是使用
CountDownLatch
。替换这个:有了这个:
然后,您将调用
notifyAll()
,而不是调用latch.countDown();
Thread2的
run
方法如下所示:# 3 楼答案
使用lock/notify一个接一个地运行两个线程的示例:
请注意,sync对象用于确保t1总是在t2之前启动