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

谁说我不能喝 提交于 2020-01-22 03:09:12

问题


My understanding is that threads in theory are executed in parallel. JVM decides; 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.

For some specific reason; I want the threads to execute in this order: t3 then t1 and then t2.

Is it possible to do this? Does java provided any way of doing this?


回答1:


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.




回答2:


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.




回答3:


Since java 8 this has become very easy using CompletableFuture :

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



回答4:


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().

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. Thread B could wait() in a loop, checking the value of that variable. Then when it was safe for thread B to run, thread A could set the variable and wake thread B up using notify().

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.




回答5:


You can join a thread on another so he'll run when the other one finishes.




回答6:


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



来源:https://stackoverflow.com/questions/11234757/is-it-possible-to-define-execution-order-for-a-set-of-threads-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!