简体   繁体   English

是否可以在java中定义一组线程的执行顺序

[英]is it possible to define execution order for a set of threads in java

My understanding is that threads in theory are executed in parallel.我的理解是理论上线程是并行执行的。 JVM decides; JVM 决定; when a resource is available which thread to pick from the waiting thread queue (based on some algorithm).当资源可用时,从等待线程队列中选择哪个线程(基于某种算法)。

Hence we can not provide/enforce a sequence of execution for threads.因此我们不能为线程提供/强制执行序列。

Say my java application has 3 threads, t1, t2 and t3.假设我的 Java 应用程序有 3 个线程,t1、t2 和 t3。

For some specific reason;由于某些特定原因; I want the threads to execute in this order: t3 then t1 and then t2.我希望线程按以下顺序执行:t3 然后 t1 然后 t2。

Is it possible to do this?是否有可能做到这一点? Does java provided any way of doing this? java是否提供了任何方法来做到这一点?

Use an Executor:使用执行器:

executor.execute(runnable1);
wait();
executor.execute(runnable2);
wait();
executor.execute(runnable3);
wait();

And of course, each Runnable has to end with a notify() statement.当然,每个 Runnable 都必须以notify()语句结束。

Don't use threads , is the straightforward answer.不要使用线程,这是直接的答案。

If you don't want code to run out of order, then why are you using threads at all?如果您不希望代码无序运行,那么您为什么要使用线程呢? Just execute things step by step like normal.只需像往常一样一步一步地执行。

If you want certain parts of the threads to run in order, then use standard concurrency mechanisms like locks, wait/notify, and semaphores, but if you just want whole operations to run in a specific order, then...run them in order.如果您希望线程的某些部分按顺序运行,则使用标准的并发机制,如锁、等待/通知和信号量,但如果您只想按特定顺序运行整个操作,那么...按顺序运行它们. Without threads.没有螺纹。

Since java 8 this has become very easy using CompletableFuture :从 java 8 开始,使用CompletableFuture变得非常容易:

CompletableFuture.runAsync(runnable3)
            .thenRunAsync(runnable1)
            .thenRunAsync(runnable2);

You cannot tell the thread scheduler which order to execute threads in. If you need to ensure that a certain piece of code which is running on thread A must run before another piece of code running on thread B, you must enforce that order using locks or wait() / notify() .您无法告诉线程调度程序以哪个顺序执行线程。如果您需要确保在线程 A 上运行的某段代码必须在线程 B 上运行的另一段代码之前运行,则必须使用锁或wait() / notify()

For example, you could use a variable which was accessible to both threads as a "flag" to indicate whether it is safe for thread B to go ahead.例如,您可以使用两个线程都可以访问的变量作为“标志”来指示线程 B 继续运行是否安全。 Thread B could wait() in a loop, checking the value of that variable.线程 B 可以在循环中使用wait() ,检查该变量的值。 Then when it was safe for thread B to run, thread A could set the variable and wake thread B up using notify() .然后,当线程 B 可以安全运行时,线程 A 可以设置变量并使用notify()唤醒线程 B。

So yes, it is possible to enforce a desired order between things which happen on different threads.所以是的,可以在不同线程上发生的事情之间强制执行所需的顺序。 Generally, though, you want to avoid writing such low-level, detailed code.但是,一般来说,您希望避免编写如此低级、详细的代码。 It is just too easy to get things wrong and cause subtle, hard-to-find bugs.把事情弄错并导致微妙的、难以发现的错误太容易了。 When you are dealing with multithreaded code, always try to use high-level building blocks if you can.当您处理多线程代码时,如果可以,请始终尝试使用高级构建块。

您可以在另一个线程上加入一个线程,以便他在另一个线程完成时运行。

You can set order for your threads.您可以为您的线程设置顺序。

I've tried to modelling your situation:我试图模拟你的情况:

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());
    }
}

Output:输出:

Started thread: first
Started thread: second
Thread is going die: first
Thread is going die: second
Current thread is going die

summary: With .join() method we can move current thread to Runnable state until the time when "joined thread" will dead总结:使用.join()方法,我们可以将当前线程移动到 Runnable 状态,直到“加入的线程”死亡

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM