running 3 threads in sequence java

前端 未结 10 563
天涯浪人
天涯浪人 2020-11-29 04:35

I have 3 threads 1st printing A 2nd printing B 3rd printing C

I want to print in sequence A B C A B C A B C and so on.....

So I wrote the program below, but

相关标签:
10条回答
  • 2020-11-29 05:14

    I was asked to write a similar program in an interview with the added condition that it should be extensible in a way that we can provide our own count of threads and they should print characters with the first thread printing 'A' and then the subsequent threads printing B, C, D and so on. Here's how I did it.

    public class AlternateCharPrinter {
    
        public static char ch = 65;
    
        private static void createAndStartThreads(int count) {
            Object lock = new Object();
            for (int i = 0; i < count; i++) {
                new Thread(new AlternateCharRunner((char) (65 + i), lock)).start();
            }
    
        }
    
        public static void main(String[] args) {
            createAndStartThreads(4);
        }
    
    }
    
    class AlternateCharRunner implements Runnable {
    
        private char ch;
        private Object lock;
        private static int runnerCount;
    
        public AlternateCharRunner(char ch, Object lock) {
            this.ch = ch;
            this.lock = lock;
            runnerCount++;
        }
    
        @Override
        public void run() {
            while (true) {
                synchronized (lock) {
                    while (ch != AlternateCharPrinter.ch) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(AlternateCharPrinter.ch++);
                    if (AlternateCharPrinter.ch == (65 + runnerCount)) {
                        AlternateCharPrinter.ch = 65;
                    }
                    lock.notifyAll();
                }
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 05:15
     public class RunThreadsInOrder implements Runnable {
    
        static int numThread = 1;
        static int threadAllowedToRun = 1;
        int myThreadID;
        private static Object myLock = new Object();
    
        public RunThreadsInOrder() {
            this.myThreadID = numThread++;
            System.out.println("Thread ID:" + myThreadID);
        }
    
        @Override
        public void run() {
            synchronized (myLock) {
                while (myThreadID != threadAllowedToRun) {
                    try {
                        myLock.wait();
                    } catch (InterruptedException e) {
    
                    } catch (Exception e) {}
                }
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
    
                System.out.println("myThreadID is running: " + myThreadID);
                myLock.notifyAll();
                threadAllowedToRun++;
            }
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            Thread t1 = new Thread(new RunThreadsInOrder());
            Thread t2 = new Thread(new RunThreadsInOrder());
            Thread t3 = new Thread(new RunThreadsInOrder());
            Thread t4 = new Thread(new RunThreadsInOrder());
            Thread t5 = new Thread(new RunThreadsInOrder());
            Thread t6 = new Thread(new RunThreadsInOrder());
            Thread t7 = new Thread(new RunThreadsInOrder());
    
            t7.start();
            t6.start();
            t5.start();
            t4.start();
            t3.start();
            t2.start();
            t1.start();
    
        }
    }
    
    0 讨论(0)
  • 2020-11-29 05:16

    The simplest solution to solve this can be following way:

    public class PrintInOrder implements Runnable {
    
    private int valueToPrint;
    private int id;
    private static int turn = 1;
    private static int RESET_TURN_THRESHOLD = 3;
    
    public PrintInOrder() {
        this.valueToPrint = -1;
    }
    
    public PrintInOrder(int id, int val) {
        this.id = id;
        this.valueToPrint = val;
    }
    
    @Override
    public void run() {
            while(true) {
                if (turn == this.id) {
                    System.out.println(Thread.currentThread().getName() + "::::" + valueToPrint);
                    turn++;
                }
                if (turn > RESET_TURN_THRESHOLD) {
                    turn = 1;
                }
            }
    
    }
    
    public static void main(String []args) {
        Thread t1 = new Thread(new PrintInOrder(1, 1));
        t1.setName("THREAD-1");
        t1.start();
        Thread t2 = new Thread(new PrintInOrder(2, 2));
        t2.setName("THREAD-2");
        t2.start();
        Thread t3 = new Thread(new PrintInOrder(3, 3));
        t3.setName("THREAD-3");
        t3.start();
    }
    

    }

    /*
    OUTPUT::::
    THREAD-1::::1
    THREAD-2::::2
    THREAD-3::::3
    THREAD-1::::1
    THREAD-2::::2
    THREAD-3::::3
    THREAD-1::::1
    THREAD-2::::2
    THREAD-3::::3
    THREAD-1::::1
    THREAD-2::::2
    THREAD-3::::3
    THREAD-1::::1
    THREAD-2::::2
    THREAD-3::::3
    THREAD-1::::1
    THREAD-2::::2
    THREAD-3::::3
    ...
    */
    
    0 讨论(0)
  • 2020-11-29 05:17

    Convert those IF statements to WHILE statements to get the desired behavior:

    if (notifyAllExample.status != 2){
        notifyAllExample.wait();
    }
    

    to

    while (notifyAllExample.status != 2){
        notifyAllExample.wait();
    }
    

    This will ensure that if a thread is notified, it won't go out of the while loop until the status value is what it expects.

    Also, mark status as volatile so that the threads won't have a local copy.

    0 讨论(0)
  • 2020-11-29 05:19

    Here is my solution -

    I have created three threads each thread knows what it needs to print and what comes after it.

    I have also created a Class NLock which holds the next word which needs to be printed.

    Whenever a thread is able to acquire NLock lock then it checks if it's his turn if yes then it prints the word and set the next value to be printed in NLock or else it waits till it's his turn

    public class SynchronizeThreeThreads {
    
        public static void main(String args[]) throws InterruptedException {
            NLock lock=new NLock("A");
            Thread a =new Thread(new PrintInOrder("A","B",lock));
            Thread b =new Thread(new PrintInOrder("B","C",lock));
            Thread c =new Thread(new PrintInOrder("C","A",lock));
    
            a.start();
            b.start();
            c.start();
            c.join(); // Once all is done main thread will exit
            System.out.println("Done");
        }
    }
    
    class NLock{
         private String value;
    
         public NLock(String value) {
             this.value=value;
         }
    
         public String getValue() {
             return value;
         }
    
         public void setValue(String next) {
             this.value=next;
         }
    
    }
    
    class PrintInOrder implements Runnable{
    
        private String word;
    
        private String next;
    
        private NLock lock;
    
        public PrintInOrder(String word, String next,NLock lock){
            this.word=word;
            this.next=next;
            this.lock=lock;
        }
    
        @Override
        public void run() {
            int i=0;
            while(i<3) {
                synchronized (lock) {
                    try {
                        //Check if it's my turn
                        if(lock.getValue().equals(word)) {
                            System.out.println(this.word);
                            //Set what next needs to be printed
                            //So that when that thread wakes up it knows that it's his turn
                            lock.setValue(next);
                            i++;
                            lock.notifyAll();
                            Thread.sleep(100);
                        }
                        else //Nope not my turn wait
                            lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }
    

    Below is the output

    A B C A B C A B C Done

    0 讨论(0)
  • 2020-11-29 05:22

    Replace:

    if(notifyAllExample.status!=1){
       notifyAllExample.wait();
    }
    

    with:

    while(notifyAllExample.status!=1){
       notifyAllExample.wait();
    }
    

    in all classes accordingly.

    0 讨论(0)
提交回复
热议问题