我有4个线程在运行,即A,B,C,D。 根据某些输入条件,执行顺序是变化的。 例如,对于输入" 0",序列将是A-> C-> B-D 对于输入" 1",序列将是A-> D-> B-C
答案 0 :(得分:1)
通常,您不应该想要以如此精细的细节控制线程。但是,有时需要。以编写测试用例为例。所以我为此准备了一个线程调度程序:
滚动到文件的底部,您可以看到有一个main method来说明此类的用法。在为Java EE编写测试代码时帮助了我很多。
答案 1 :(得分:0)
您可以等待第一个线程完成然后开始下一个线程:
Thread A = ...;
Thread B = ...;
A.start(); // start thread A
A.join(); // wait here until thread A finishes
B.start();
B.join();
// and so on.
答案 2 :(得分:0)
解决此问题的可能方法如下:
应该运行线程的顺序将由您将它们插入ArrayList的顺序控制。
完整的工作示例如下:
public class ThreadSequencer {
private static List<Thread> threadSequence = new ArrayList<>();
/*Create the threads. If not using Java 8, replace ThreadSequencer::printThreadName
* with new Runnable() { public void run() { System.out.println(Thread.currentThread().getName());} }
*/
private static Thread threadA = new Thread(ThreadSequencer::printThreadName);
private static Thread threadB = new Thread(ThreadSequencer::printThreadName);
private static Thread threadC = new Thread(ThreadSequencer::printThreadName);
private static Thread threadD = new Thread(ThreadSequencer::printThreadName);
private static void sequenceThreads(String input) {
threadSequence.clear();
if("0".equals(input)) {
threadSequence.add(threadA);
threadSequence.add(threadB);
threadSequence.add(threadC);
threadSequence.add(threadD);
} else if("1".equals(input)) {
threadSequence.add(threadB);
threadSequence.add(threadA);
threadSequence.add(threadC);
threadSequence.add(threadD);
}
}
public static void runThreads(String input) {
sequenceThreads(input);
for(Thread thread : threadSequence) {
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
//handle exceptional cases
e.printStackTrace();
}
}
}
private static void printThreadName() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String []args) {
runThreads("1");
}
}
使用String调用runThreads方法,线程将按该序列运行。话虽这么说,如果你不想按顺序运行线程,为什么要首先创建线程?
答案 3 :(得分:-1)
这个答案基于OPs表示法的假设读数, “X-> Y-Z”表示“线程X在Y和Z开始之前运行完成”。
修补工程。 Fouad回答OP的情况:
Thread A = ...;
Thread B = ...;
Thread C ...
Thread D ...
if (input==0)
{ A.start(); // start thread A
A.join(); // wait here until thread A finishes
C.start();
C.join();
B.start();
D.start();
B.join();
D.join();
}
else
{ A.start();
A.join();
D.start();
D.join();
B.start();
C.start();
B.join();
C.join();
}
作为一种轻微的优化,A.start(); A.join()语句对可以提升到条件之上。
OP似乎想要做的是在线程上定义动态部分订单。他的具体例子如上所述是可以解决的。通常,父线程使用“开始”和“连接”不能完成静态部分顺序(上面“if”的每个臂);各个线程必须进行连接以确保以正确的顺序调用它们。要执行动态部分订单,每个线程都必须根据条件检查前置任务。
假设输入== 0导致A-> B,A-> C,D-> C,否则A-> D,B-> D,B-> C: 你需要一个更加混乱的解决方案(原谅我的Java,我不是专家):
Thread A = new Thread(workerA)...;
Thread B = new Thread(workerB)...;
Thread C = new Thread(workerC)...;
Thread D = new Thread(workerD)...;
workerA() {
...
}
workerB() {
if (input==0)
A.join();
...
}
workerC() {
if (input==0)
{ A.join(); D.join(); }
else B.join();
...
}
workerD() {
if (input==1)
{ A.join(); B.join(); }
...
}
A.start(); // start thread A
B.start();
C.start();
D.start();
if (input==0)
{ B.join(); C.join(); }
else { C.join(); D.join(); }
我假设Java线程可以看到父线程中的变量(如果布局合理)。我还假设您可以多次加入一个主题,例如,从各个地方多次调用A.join()都可以。
如果您有10-12个具有复杂偏序的线程,则很难编写并正确使用它。有些语言可以直接表达部分订单,以避免编写所有启动/加入goo。