Ordering threads to run in the order they were created/started

前端 未结 10 1087
礼貌的吻别
礼貌的吻别 2020-11-30 06:15

How can i order threads in the order they were instantiated.e.g. how can i make the below program print the numbers 1...10 in order.

public class ThreadOrder         


        
相关标签:
10条回答
  • 2020-11-30 06:33

    If you need that fine-grained control, you should not use threads but instead look into using a suitable Executor with Callables or Runnables. See the Executors class for a wide selection.

    0 讨论(0)
  • 2020-11-30 06:34

    You can chain them – that is, have the first one start the second, the second start the third, etc. They won't really be running at the same time except for a bit of overlap when each one is started.

    public class ThreadOrdering
    {
        public static void main(String[] args)
        {
            MyRunnable[] threads = new MyRunnable[10];//index 0 represents thread 1;
            for(int i=1; i<=10; i++)
                threads[i] = new MyRunnable(i, threads); 
            new Thread(threads[0].start);  
        }
    }
    
    public class MyRunnable extends Runnable
    {
        int threadNumber;
        MyRunnable[] threads;
    
        public MyRunnable(int threadNumber, MyRunnable[] threads)
        {
            this.threadnumber = threadnumber;
            this.threads = threads;
        }
    
        public void run()
        {
            System.out.println(threadnumber);
            if(threadnumber!=10)
                new Thread(threadnumber).start();
        }
    }
    
    0 讨论(0)
  • 2020-11-30 06:38

    Sounds like you want ExecutorService.invokeAll, which will return results from worker threads in a fixed order, even though they may be scheduled in arbitrary order:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class ThreadOrdering {
    
        static int NUM_THREADS = 10;
    
        public static void main(String[] args) {
            ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
            class MyCallable implements Callable<Integer> {
                private final int threadnumber;
    
                MyCallable(int threadnumber){
                    this.threadnumber = threadnumber;
                }
    
                public Integer call() {
                    System.out.println("Running thread #" + threadnumber);
                    return threadnumber;
                }
            }
    
            List<Callable<Integer>> callables =
                new ArrayList<Callable<Integer>>();
            for(int i=1; i<=NUM_THREADS; i++) {
                callables.add(new MyCallable(i));
            }
            try {
                List<Future<Integer>> results =
                    exec.invokeAll(callables);
                for(Future<Integer> result: results) {
                    System.out.println("Got result of thread #" + result.get());
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } catch (ExecutionException ex) {
                ex.printStackTrace();
            } finally {
                exec.shutdownNow();
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-11-30 06:44

    A simple solution would be to use an array A of locks (one lock per thread). When thread i begins its executions, it acquires its associated lock A[i]. When it's ready to merge its results, it releases its lock A[i] and waits for locks A[0], A[1], ..., A[i - 1] to be released; then it merges the results.

    (In this context, thread i means the i-th launched thread)

    I don't know what classes to use in Java, but it must be easy to implement. You can begin reading this.

    If you have more questions, feel free to ask.

    0 讨论(0)
  • 2020-11-30 06:45

    Control of thread execution order may be implemented quite easily with the semaphores. The code attached is based on the ideas presented in Schildt's book on Java (The complete reference....). // Based on the ideas presented in: // Schildt H.: Java.The.Complete.Reference.9th.Edition.

    import java.util.concurrent.Semaphore;
    
    class Manager {
        int n;
    // Initially red on semaphores 2&3; green semaphore 1.
        static Semaphore SemFirst = new Semaphore(1);
        static Semaphore SemSecond = new Semaphore(0);
        static Semaphore SemThird = new Semaphore(0);
    
    void firstAction () {
        try {
            SemFirst.acquire();
        } catch(InterruptedException e) {
            System.out.println("Exception InterruptedException catched");
        }
        System.out.println("First: " );
        System.out.println("-----> 111");
        SemSecond.release();
    }
    void secondAction() {
        try{
            SemSecond.acquire();
        } catch(InterruptedException e) {
            System.out.println("Exception InterruptedException catched");
        }
        System.out.println("Second: ");
        System.out.println("-----> 222");
        SemThird.release();
    }
    void thirdAction() {
        try{
            SemThird.acquire();
        } catch(InterruptedException e) {
            System.out.println("Exception InterruptedException catched");
        }
        System.out.println("Third: ");
        System.out.println("-----> 333");
        SemFirst.release();
    }
    }
    
    class Thread1 implements Runnable {
        Manager q;
    
        Thread1(Manager q) {
        this.q = q;
        new Thread(this, "Thread1").start();
    }
    
    public void run() {
        q.firstAction();
    }
    }
    
    class Thread2 implements Runnable {
        Manager q;
    
        Thread2(Manager q) {
        this.q = q;
        new Thread(this, "Thread2").start();
    }
    
    public void run() {
        q.secondAction();
    }
    }
    
    class Thread3 implements Runnable {
        Manager q;
    
        Thread3(Manager q) {
        this.q = q;
        new Thread(this, "Thread3").start();
    }
    
    public void run() {
        q.thirdAction();
    }
    }
    
    class ThreadOrder {
        public static void main(String args[]) {
        Manager q = new Manager();
        new Thread3(q);
        new Thread2(q);
        new Thread1(q);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 06:51

    "I actually have some parts that i want to execute in parallel, and then once the results are generated, I want to merge the results in certain order." Thanks, this clarifies what you're asking.

    You can run them all at once, but the important thing is to get their results in order when the threads finish their computation. Either Thread#join() them in the order in which you want to get their results, or just Thread#join() them all and then iterate through them to get their results.

    // Joins the threads back to the main thread in the order we want their results.
    public class ThreadOrdering {
        private class MyWorker extends Thread {
            final int input;
            int result;
            MyWorker(final int input) {
                this.input = input;
            }
            @Override
            public void run() {
                this.result = input; // Or some other computation.
            }
            int getResult() { return result; }
        }
    
        public static void main(String[] args) throws InterruptedException {
            MyWorker[] workers = new MyWorker[10];
            for(int i=1; i<=10; i++) {
                workers[i] = new MyWorker(i);
                workers[i].start();
            }
    
            // Assume it may take a while to do the real computation in the threads.
    
            for (MyWorker worker : workers) {
                // This can throw InterruptedException, but we're just passing that.
                worker.join();
                System.out.println(worker.getResult());
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题