我的理解是理论上线程是并行执行的。JVM决定;当资源可用时,从等待线程队列中选择哪个线程(基于某种算法)。
因此,我们不能为线程提供/强制执行序列。
假设我的 java 应用程序有 3 个线程,t1、t2 和 t3。
出于某种特定原因;我希望线程按以下顺序执行:t3 然后 t1 然后 t2。
是否有可能做到这一点?java是否提供了任何方法来做到这一点?
我的理解是理论上线程是并行执行的。JVM决定;当资源可用时,从等待线程队列中选择哪个线程(基于某种算法)。
因此,我们不能为线程提供/强制执行序列。
假设我的 java 应用程序有 3 个线程,t1、t2 和 t3。
出于某种特定原因;我希望线程按以下顺序执行:t3 然后 t1 然后 t2。
是否有可能做到这一点?java是否提供了任何方法来做到这一点?
使用执行器:
executor.execute(runnable1);
wait();
executor.execute(runnable2);
wait();
executor.execute(runnable3);
wait();
当然,每个 Runnable 都必须以notify()
语句结尾。
不要使用线程,是直接的答案。
如果您不希望代码乱序运行,那么您为什么要使用线程呢?像往常一样一步一步地执行事情。
如果您希望线程的某些部分按顺序运行,则使用标准并发机制,如锁、等待/通知和信号量,但如果您只是希望整个操作按特定顺序运行,那么...按顺序运行它们. 没有线程。
自 java 8 以来,这变得非常容易使用CompletableFuture
:
CompletableFuture.runAsync(runnable3)
.thenRunAsync(runnable1)
.thenRunAsync(runnable2);
您无法告诉线程调度程序执行线程的顺序。如果您需要确保在线程 A 上运行的某段代码必须在线程 B 上运行的另一段代码之前运行,则必须使用锁或强制执行该顺序wait()
/ notify()
。
例如,您可以使用两个线程都可以访问的变量作为“标志”来指示线程 B 继续执行是否安全。线程 B 可以wait()
在一个循环中检查该变量的值。然后当线程 B 可以安全运行时,线程 A 可以设置变量并使用notify()
.
所以是的,可以在不同线程上发生的事情之间强制执行所需的顺序。不过,一般来说,您希望避免编写如此低级、详细的代码。很容易出错并导致微妙的、难以发现的错误。在处理多线程代码时,如果可以,请始终尝试使用高级构建块。
您可以在另一个线程上加入一个线程,这样他就会在另一个线程完成时运行。
我试图模拟你的情况:
public class ThreadJoinExample {
private static final Thread FIRST = new Thread( new RunnableImpl(), "first" );
private static final Thread SECOND = new Thread( new RunnableImpl(), "second" );
public static void main(String[] args) {
//here have started current thread or "main" thread that will control above threads
FIRST.start();
//waiting 2 seconds, "stop" your current thread and after current thread will start this "t3" thread until it will dead
try {
FIRST.join(2000);
} catch (InterruptedException e) {
System.out.println();
e.printStackTrace();
}
SECOND.start();
//"stop" your current thread immediately and run "t1" thread until it will dead.
try {
SECOND.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//Or we can wait for all threads and in the end - finish current main thread
try {
FIRST.join();
SECOND.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Current thread is going die");
}
}
class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println("Started thread: "+Thread.currentThread().getName());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread is going die: "+Thread.currentThread().getName());
}
}
输出:
Started thread: first
Started thread: second
Thread is going die: first
Thread is going die: second
Current thread is going die
摘要:使用.join()方法,我们可以将当前线程移动到 Runnable 状态,直到“加入的线程”死掉