I'm not sure if I fully understood the question, but it seems like a situation where we want to print topics in order. One example is printing a value using streams in the following sequence:
Thread - 0 pin: 1
Thread - 1 outlet: 2
Thread - 2 outlets: 3
Thread - 0 pin: 4
Thread - 1 outlet: 5
Thread - 2 outputs: 6, etc.
If this is a requirement, then we can write a general solution for n threads, where each thread will wait for its turn (using a common object for which it will try to obtain a 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 the worker thread will do its job and will use an instance of the above class to lock:
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 it can be checked 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(); } }
i_am_zero
source share