3 Threads Printing numbers in sequence

  public class TestClass {

    private volatile Integer count = 1;
    private volatile Integer threadIdToRun = 1;
    private Object object = new Object();

    public static void main(String[] args) {

        TestClass testClass = new TestClass();
        Thread t1 = new Thread(testClass.new Printer(1));
        Thread t2 = new Thread(testClass.new Printer(2));
        Thread t3 = new Thread(testClass.new Printer(3));

        t1.start();
        t2.start();
        t3.start();
    }

    class Printer implements Runnable {

        private int threadId;

        public Printer(int threadId) {
            super();
            this.threadId = threadId;
        }

        @Override
        public void run() {
            try {
                while (count <= 20) {
                    synchronized (object) {
                        if (threadId != threadIdToRun) {
                            object.wait();
                        } else {
                            System.out.println("Thread " + threadId + " printed " + count);
                            count += 1;

                            if (threadId == 1)
                                threadIdToRun = 2;
                            else if (threadId == 2)
                                threadIdToRun = 3;
                            else if (threadId == 3)
                                threadIdToRun = 1;

                            object.notifyAll();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}

Above program gives output

Thread 1 printed 1
Thread 2 printed 2
Thread 3 printed 3
Thread 1 printed 4
Thread 2 printed 5
Thread 3 printed 6
Thread 1 printed 7
Thread 2 printed 8
Thread 3 printed 9
Thread 1 printed 10
Thread 2 printed 11
Thread 3 printed 12
Thread 1 printed 13
Thread 2 printed 14
Thread 3 printed 15
Thread 1 printed 16
Thread 2 printed 17
Thread 3 printed 18
Thread 1 printed 19
Thread 2 printed 20

Though this is a bad way for using threads, if we still want it a generic solution can be to have a worker thread which will store its id:

class Worker extends Thread {
    private final ResourceLock resourceLock;
    private final int threadNumber;
    private final AtomicInteger counter;
    private volatile boolean running = true;
    public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) {
        this.resourceLock = resourceLock;
        this.threadNumber = threadNumber;
        this.counter = counter;
    }
    @Override
    public void run() {
        while (running) {
            try {
                synchronized (resourceLock) {
                    while (resourceLock.flag != threadNumber) {
                        resourceLock.wait();
                    }
                    System.out.println("Thread:" + threadNumber + " value: " + counter.incrementAndGet());
                    Thread.sleep(1000);
                    resourceLock.flag = (threadNumber + 1) % resourceLock.threadsCount;
                    resourceLock.notifyAll();
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
        }
    }
    public void shutdown() {
        running = false;
    }
}

The ResourceLock class would store flag and max threads count:

class ResourceLock {
    public volatile int flag;
    public final int threadsCount;

    public ResourceLock(int threadsCount) {
        this.flag = 0;
        this.threadsCount = threadsCount;
    }
}

And then main class can use it as below:

public static void main(String[] args) throws InterruptedException {
        final int threadsCount = 3;
        final ResourceLock lock = new ResourceLock(threadsCount);
        Worker[] threads = new Worker[threadsCount];
        final AtomicInteger counter = new AtomicInteger(0);
        for(int i=0; i<threadsCount; i++) {
            threads[i] = new Worker(lock, i, counter);
            threads[i].start();
        }
        Thread.sleep(10000);
        System.out.println("Will try to shutdown now...");
        for(Worker worker: threads) {
            worker.shutdown();
        }
    }

Here after a certain delay we may like to stop the count and the method shutdown in worker provides this provision.


Well, the problem is that modulo 3 % 3 is 0. Change your threadIds to 0..2 instead of 1..3 and hopefully it should work.