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

前端 未结 10 1088
礼貌的吻别
礼貌的吻别 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:56

    Simply put, the scheduling of threads is indeterminate.

    http://www.janeg.ca/scjp/threads/scheduling.html Dead domain - do not click

    WaybackMachine version of the above page

    The longer answer is that if you want to do this, you'll need to manually wait for each thread to complete its work before you allow another to run. Note that in this fashion, all the threads will still interleave but they won't accomplish any work until you give the go-ahead. Have a look at the synchronize reserved word.

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

    This can be done without using synchronized keyword and with the help of volatile keyword. Following is the code.

    package threadOrderingVolatile;
    
    public class Solution {
        static volatile int counter = 0;
        static int print = 1;
        static char c = 'A';
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Thread[] ths = new Thread[4];
            for (int i = 0; i < ths.length; i++) {
                ths[i] = new Thread(new MyRunnable(i, ths.length));
                ths[i].start();
            }
        }
    
        static class MyRunnable implements Runnable {
            final int thID;
            final int total;
    
            public MyRunnable(int id, int total) {
                thID = id;
                this.total = total;
            }
    
            @Override
            public void run() {
                while(true) {
                    if (thID == (counter%total)) {
                        System.out.println("thread " + thID + " prints " + c);
                        if(c=='Z'){
                            c='A';
                        }else{
                            c=(char)((int)c+1);
                        }
                        System.out.println("thread " + thID + " prints " + print++);
                        counter++;                  
                    } else {
                        try {
                            Thread.sleep(30);
                        } catch (InterruptedException e) {
                            // log it
                        }
                    }
                }
            }
    
        }
    
    }
    

    Following is the github link which has a readme, that gives detailed explanation about how it happens. https://github.com/sankar4git/volatile_thread_ordering

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

    Here's a way to do it without having a master thread that waits for each result. Instead, have the worker threads share an object which orders the results.

    import java.util.*;
    
    public class OrderThreads {
        public static void main(String... args) {
            Results results = new Results();
            new Thread(new Task(0, "red", results)).start();
            new Thread(new Task(1, "orange", results)).start();
            new Thread(new Task(2, "yellow", results)).start();
            new Thread(new Task(3, "green", results)).start();
            new Thread(new Task(4, "blue", results)).start();
            new Thread(new Task(5, "indigo", results)).start();
            new Thread(new Task(6, "violet", results)).start();
        }
    }
    
    class Results {
        private List<String> results = new ArrayList<String>();
        private int i = 0;
    
        public synchronized void submit(int order, String result) {
            while (results.size() <= order) results.add(null);
            results.set(order, result);
            while ((i < results.size()) && (results.get(i) != null)) {
                System.out.println("result delivered: " + i + " " + results.get(i));
                ++i;
            }
        }
    }
    
    
    class Task implements Runnable {
        private final int order;
        private final String result;
        private final Results results;
    
        public Task(int order, String result, Results results) {
            this.order = order;
            this.result = result;
            this.results = results;
        }
    
        public void run() {
            try {
                Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
            }
            catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
            System.out.println("task finished: " + order + " " + result);
            results.submit(order, result);
        }
    }
    
    0 讨论(0)
  • 2020-11-30 06:59
    public static void main(String[] args) throws InterruptedException{
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r,"A");
        Thread t2 = new Thread(r,"B");
        Thread t3 = new Thread(r,"C");
    
        t1.start();
        Thread.sleep(1000);
    
        t2.start();
        Thread.sleep(1000);
        t3.start();
    }
    
    0 讨论(0)
提交回复
热议问题