Multi Thread Synchronization by locks in java

Following java code prints natural numbers in sequence by multiple threads. Number of threads can be changed by the field "numOfThreads".
If numOfThreads is 3, output will be like:
Thread 1 -1, Thread 2- 2, Thread 3- 3, Thread 1- 4, Thread 2- 5 and so on till a max value defined by field "maxValue".



package multi.thread.abc;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MultiThreadSync {

private static final int numOfThreads = 4;
private static final int maxValue = 20;
private final CyclicBarrier barrier;
private final Counter counter;
private final Thread[] threads;

public MultiThreadSync () {
counter = new Counter(numOfThreads, maxValue);
barrier = new CyclicBarrier(numOfThreads + 1);
threads = new Thread[numOfThreads];

for (int i=0; i<numOfThreads; i++) {
threads[i] = new Thread(new DemoThread(barrier, counter, i), getThreadName(i));
}
}

private String getThreadName(int i) {
return "Thread " + ++i;
}

public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
MultiThreadSync mts = new MultiThreadSync();
mts.runAllThreads();
}

private void runAllThreads() throws InterruptedException, BrokenBarrierException {
for (int i = 0; i < numOfThreads; i++) {
threads[i].start();
}

Thread.sleep(1500);
System.out.println("MAIN: GREEN Signal to counting threads!");
barrier.await();

for (int i = 0; i < numOfThreads; i++) {
threads[i].join();
}
}

}

class DemoThread implements Runnable {
private CyclicBarrier barrier;
private Counter counter;
private int threadId;

public DemoThread(CyclicBarrier barrier, Counter counter, int threadId) {
this.barrier = barrier;
this.counter = counter;
this.threadId = threadId;
}

@Override
public void run() {
System.out.println(Thread.currentThread().getName() + ": Waiting for GREEN Signal from MAIN...");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
while (!(counter.isMaxValueReached())) {
counter.printSeries(threadId);
}
counter.signalAll(threadId);
}
}

class Counter {
private int value = 0;
private int numOfThreads;
private int maxValue;
private final Lock lock = new ReentrantLock(true);
private final Condition intCondition = lock.newCondition();

public Counter(int numOfThreads, int maxValue) {
this.numOfThreads = numOfThreads;
this.maxValue = maxValue;
}

public void signalAll(int threadId) {
try {
lock.lockInterruptibly();
intCondition.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void printSeries(int threadId) {
try {
lock.lock();
if (!(isMyTurn(threadId) || this.isMaxValueReached())) {
intCondition.await();
} else if (this.isMaxValueReached()) {
intCondition.signalAll();
} else {
System.out.println(Thread.currentThread().getName() + ": " + ++value);
intCondition.signalAll();
Thread.sleep(500);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}

}

private boolean isMyTurn(int threadId) {
return value % numOfThreads == threadId;
}

public boolean isMaxValueReached() {
return this.value >= this.maxValue ? true : false;
}
}

Comments

Popular posts from this blog

JMeter – Working with JSON

Hyperlocal Startups Creating a Better Living

Existence: Absolute & Relative