【发布时间】:2021-01-24 04:17:29
【问题描述】:
这应该是多线程的一个简单问题:https://leetcode.com/problems/print-in-order/ “Foo的同一个实例会被传递给三个不同的线程。线程A会调用first(),线程B会调用second(),线程C会调用third()。设计一个机制,修改程序为确保 second() 在 first() 之后执行,third() 在 second() 之后执行” 他们给出了这段代码:
public Foo() {}
public void first(Runnable printFirst) throws InterruptedException {
// printFirst.run() outputs "first". Do not change or remove this line.
printFirst.run();
}
public void second(Runnable printSecond) throws InterruptedException {
// printSecond.run() outputs "second". Do not change or remove this line.
printSecond.run();
}
public void third(Runnable printThird) throws InterruptedException {
// printThird.run() outputs "third". Do not change or remove this line.
printThird.run();
}
**似乎我可以使用 Thread.join 解决它,如下所示,但我不明白的是为什么他们将 Runnable 的实例传递给每个方法,以及如何正确地做到这一点,因为下面的代码将打印每条消息两次——一次是因为 Thread.start() 将调用相应的 run() 方法,一次是直接调用该方法。我知道这是错误的方法,但是如果我们尝试使用 join 方法,则无法弄清楚什么是正确的解决方案。 **
public Foo() throws InterruptedException {
Runnable r1 = () -> {
System.out.println("first ");
};
first(r1);
Runnable r2 = () -> {
System.out.println("second ");
};
second(r2);
Runnable r3 = () -> {
System.out.println("third ");
};
third(r3);
Thread t1 = new Thread(r1);
t1.start();
try {
t1.join(); // wait for this thread to finish before starting #2
}
catch(Exception e) {
System.err.println("Thread 1 error");
}
Thread t2 = new Thread(r2);
t2.start();
try {
t2.join();
}
catch(Exception e) {
System.err.println("Thread 2 error");
}
Thread t3 = new Thread(r3);
t3.start();
try {
t3.join();
}
catch(Exception e) {
System.err.println("Thread 3 error");
}
}```
【问题讨论】:
-
使用
join解决不了,线程需要异步执行。您需要以满足要求的方式更改firstsecond和third方法。线程是如何启动的不是你可以篡改的。一个简单的 google 搜索会显示一堆解决方案,例如hezhigang.github.io/2019/08/08/… -
您可以在线程之间使用信号,例如此处所述tutorials.jenkov.com/java-concurrency/thread-signaling.html
标签: java multithreading runnable