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 threadId
s to 0..2
instead of 1..3
and hopefully it should work.