访谈:如何确保一个接一个的线程运行?

Ash*_*hok 18 java multithreading

有线程T1,T2并且T3,我们如何确保线程T2运行之后T1和线程T3运行T2

我的采访中提到了这个问题.我没回答.请详细解释.

Mar*_*nik 25

这将是最简单,最愚蠢的方法:

final Thread t1 = new Thread(new T1()); // assume T1 is a Runnable
t1.start();
t1.join();
final Thread t2 = new Thread(new T2());
t2.start();
t2.join();
final Thread t3 = new Thread(new T3());
t3.start();
t3.join();
Run Code Online (Sandbox Code Playgroud)

  • 来吧 - 你抱怨我按顺序运行我的runnables!你至少可以让它们有些平行! (3认同)
  • @assylias这正是我解释它的方式.对于这个用例,您的解决方案是一个真正的现实世界胜利,因为每个人都会同意,但这会满足所述的要求. (3认同)

Mar*_*mes 6

@Assylias已经发布了最明显,最简单的方法-使用T1运行方法create / start T2和T2运行方法create / start T3。

恕我直言,这是毫无意义的,但可以做到。

使用Join()的解决方案不能回答问题-它们可以确保终止线程的顺序,而不是运行顺序。如果面试官没有做到这一点,那么您仍然需要找到另一份工作。

在接受记者采访时,我的回答是“对于*缘故,为什么?通常使用线程来避免您的要求!


Gra*_*ray 5

一种方法是这样的。虽然很复杂。您可能想为此使用java.util.concurrent.CyclicBarrier该类。

每个线程在完成时设置布尔值并通知下一个线程继续。即使它是一个AtomicBoolean类,我们也需要它,synchronized所以我们可以wait()notify()在它上面。

传入锁对象或者可能有一个begin()方法会更干净T2T3所以我们可以隐藏这些对象内部的锁。

final Object lock2 = new Object();
final Object lock3 = new Object();
boolean ready2;
boolean ready3;
...
public T1 implements Runnable {
    public void run() {
        ...
        synchronized (lock2) {
            // notify the T2 class that it should start
            ready2 = true;
            lock2.notify();
        }
    }
}
...

public T2 implements Runnable {
    public void run() {
        // the while loop takes care of errant signals
        synchronized (lock2) {
            while (!ready2) {
                lock2.wait();
            }
        }
        ...
        // notify the T3 class that it should start
        synchronized (lock3) {
            ready3 = true;
            lock3.notify();
        }
    }
}
...
public T3 implements Runnable {
    public void run() {
        // the while loop takes care of errant signals
        synchronized (lock3) {
            while (!ready3) {
                lock3.wait();
            }
        }
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)


ass*_*ias 3

线程也是可运行的。您可以简单地按顺序运行它们:

t1.run();
t2.run();
t3.run();
Run Code Online (Sandbox Code Playgroud)

这显然没什么兴趣。

假设他们希望线程并行运行,一种解决方案是让每个线程启动下一个线程,因为JMM 保证

对线程上的 start() 的调用发生在已启动线程中的任何操作之前。

  • 那么它们就不是“线程”了。它们只是物体。我怀疑这是否是面试问题的一个好答案。 (9认同)