I am not sure if I understood the question completely but this seems like a situation where we want to print the threads in sequence. One example is to print the value using threads in a sequence like:
Thread - 0 output: 1
Thread - 1 output: 2
Thread - 2 output: 3
Thread - 0 output: 4
Thread - 1 output: 5
Thread - 2 output: 6 and so on..
If this is the requirement then a generic solution for n threads can be written where each thread will wait for its turn (using common object on which it will try to acquire lock).
class ResourceLock {
private volatile int currentThreadId;
private final int totalThreads;
public ResourceLock(int threadsCount) {
this.currentThreadId = 0;
this.totalThreads = threadsCount;
}
public void assignTokenToNextThread(int currentThreadNum) {
this.currentThreadId = (currentThreadNum + 1) % totalThreads;
}
public int getCurrentThreadId() {
return currentThreadId;
}
}
Now a worker thread will do its job and use the instance of above class for locking purpose:
class Worker extends Thread {
private final ResourceLock resourceLock;
private final int threadId; // id of this thread
private final AtomicInteger counter; // counter shared by all threads, will print number in sequence.
private volatile boolean running = true; // flag to stop this thread when necessary
public Worker(ResourceLock resourceLock, int threadNumber, AtomicInteger counter) {
this.resourceLock = resourceLock;
this.threadId = threadNumber;
this.counter = counter;
}
@Override
public void run() {
while (running) {
try {
synchronized (resourceLock) {
while (resourceLock.getCurrentThreadId() != this.threadId) {
resourceLock.wait();
}
System.out.println("Thread:" + threadId + " value: " + counter.incrementAndGet());
Thread.sleep(1000);
resourceLock.assignTokenToNextThread(this.threadId);
resourceLock.notifyAll();
}
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
}
public void shutdown() {
running = false;
}
}
And this can be tested as:
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(20000);
System.out.println("Will try to shutdown now...");
for(Worker worker: threads) {
worker.shutdown();
}
}