Skip to main content

9 posts tagged with "Concurrency"

View All Tags

Create Custom Lock In Java

· One min read
Sandeep Bhardwaj

Lock.java

public class Lock {

private boolean isLocked = false;

public synchronized void lock() throws InterruptedException {
while (isLocked) {
wait();
}
isLocked = true;
}

public synchronized void unlock() {
isLocked = false;
notify();
}
}

Usage

lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}

CyclicBarrier In Java

· One min read
Sandeep Bhardwaj

CyclicBarrierExample.java

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {

public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3, new BarrierAction());

new Thread(new Party(barrier)).start();
new Thread(new Party(barrier)).start();
new Thread(new Party(barrier)).start();

try {
// sleep to avoid BrokenBarrierException
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("\nReset the barrier....\n");
// reset the barrier
barrier.reset();

new Thread(new Party(barrier)).start();
new Thread(new Party(barrier)).start();
new Thread(new Party(barrier)).start();
}

}

BarrierAction.java

public class BarrierAction implements Runnable {

@Override
public void run() {
System.out.println("Barrier Action Executes !!!");
}

}

Party.java

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Party implements Runnable {
CyclicBarrier barrier;

public Party(CyclicBarrier barrier) {
this.barrier = barrier;
}

@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " waiting at barrier.");
this.barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}

}

Output

Thread-2 waiting at barrier.
Thread-1 waiting at barrier.
Thread-0 waiting at barrier.
Barrier Action Executes !!!

Reset the barrier....

Thread-3 waiting at barrier.
Thread-4 waiting at barrier.
Thread-5 waiting at barrier.
Barrier Action Executes !!!

Semaphore In Java

· One min read
Sandeep Bhardwaj

SemaphoreExample.java

import java.util.concurrent.Semaphore;

public class SemaphoreExample {

public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2);

new Thread(new Task(semaphore)).start();
new Thread(new Task(semaphore)).start();
new Thread(new Task(semaphore)).start();
new Thread(new Task(semaphore)).start();
}

}

class Task implements Runnable {

Semaphore semaphore;

public Task(Semaphore semaphore) {
this.semaphore = semaphore;
}

@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " acquired");

Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println(Thread.currentThread().getName() + " released");
}
}
}

Output

Thread-0 acquired
Thread-1 acquired
Thread-1 released
Thread-0 released
Thread-2 acquired
Thread-3 acquired
Thread-2 released
Thread-3 released

Create Custom ThreadPool In Java

· 2 min read
Sandeep Bhardwaj

ThreadPool.java

Custom ThreadPool class with using the LinkedBlockingQueue for holding the incoming threads.

import java.util.concurrent.LinkedBlockingQueue;

public class ThreadPool
{
volatile boolean isRunning;
private LinkedBlockingQueue<Runnable> blockingQueue;
private WorkerThread[] workerThreads;

public ThreadPool(int poolSize)
{
blockingQueue = new LinkedBlockingQueue<>(4);
workerThreads = new WorkerThread[poolSize];

// create worker threads
for (int i = 0; i < poolSize; i++)
{
workerThreads[i] = new WorkerThread(i + "", blockingQueue);
}

// start all threads
for (WorkerThread workerThread : workerThreads)
{
workerThread.start();
}
}

public void execute(Runnable task)
{
synchronized (blockingQueue)
{

while (blockingQueue.size() == 4)
{
try
{
blockingQueue.wait();
} catch (InterruptedException e)
{
System.out.println("An error occurred while queue is waiting: " + e.getMessage());
}
}

blockingQueue.add(task);

// notify all worker threads waiting for new task
blockingQueue.notifyAll();
}
}
}

WorkerThread.java

import java.util.concurrent.LinkedBlockingQueue;

public class WorkerThread extends Thread
{
private LinkedBlockingQueue<Runnable> queue;

public WorkerThread(String name, LinkedBlockingQueue<Runnable> queue)
{
super(name);
this.queue = queue;
}

@Override
public void run()
{

while (true)
{
synchronized (queue)
{
while (queue.isEmpty())
{
try
{
queue.wait();
} catch (InterruptedException e)
{
System.out.println("An error occurred while queue is waiting: " + e.getMessage());
}
}

try
{
Runnable runnable = this.queue.poll();
System.out.println(
"worker " + Thread.currentThread().getName() + " executing thread " + runnable.toString());
runnable.run();
Thread.sleep(1000);

// notify threads waiting to put task in queue
queue.notifyAll();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}

}

ThreadPoolTester.java

public class ThreadPoolTester
{

public static void main(String[] args)
{
ThreadPool pool = new ThreadPool(2);

for (int i = 0; i < 10; i++)
{
pool.execute(new Task(i + ""));
}
}

}

class Task implements Runnable
{
String name;

public Task(String name)
{
this.name = name;
}

@Override
public void run()
{
System.out.println("Task " + this.name + " is running");
}

@Override
public String toString()
{
return this.name;
}
}

Output

worker 1 executing thread 0
Task 0 is running
worker 1 executing thread 1
Task 1 is running
worker 0 executing thread 2
Task 2 is running
worker 0 executing thread 3
Task 3 is running
worker 0 executing thread 4
Task 4 is running
worker 1 executing thread 5
Task 5 is running
worker 0 executing thread 6
Task 6 is running
worker 0 executing thread 7
Task 7 is running
worker 1 executing thread 8
Task 8 is running
worker 1 executing thread 9
Task 9 is running

Create Custom CountDownLatch In Java

· One min read
Sandeep Bhardwaj
CustomCountDownLatch.java
/**
* Custom CoundDownLach implementation
* @author sandeep
*
*/
public class CustomCountDownLatch
{
int counter;

public CustomCountDownLatch(int counter)
{
this.counter = counter;
}

public synchronized void await() throws InterruptedException
{
if (counter > 0)
{
wait();
}
}

/**
* method will decrement the counter by 1 each time
*/
public synchronized void countDown()
{
counter--;
if (counter == 0)
{
notifyAll();
}
}
}

BlockingQueue In Java

· One min read
Sandeep Bhardwaj
public interface BlockingQueue extends Queue

A BlockingQueue provides additionally functionality

  • wait for the queue to become non-empty when retrieving an element.
  • wait for space to become available in the queue when storing an element.

Implementing Classes:

There are 7 implemented classed of BlockingQueue

  1. ArrayBlockingQueue
  2. DelayQueue
  3. ArrayBlockingQueue
  4. LinkedBlockingDeque
  5. LinkedTransferQueue
  6. PriorityBlockingQueue
  7. SynchronousQueue

Execute N number of threads one after another in cyclic way

· 2 min read

This is a famous interview question how to execute 3 or n threads one after another and performing a job like :-

Thread T1 prints then Threads T2 print and then .... Thread Tn
then again Thread T1 prints then Threads T2 print and then .... Thread Tn and so on....

T1 -> T2 -> ... -> Tn; and then again T1 -> T2 -> ... -> Tn


CyclicExecutionOfThreads.java

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicExecutionOfThreads
{

public static void main(String args[])
{

int totalNumOfThreads = 10;
PrintJob printJob = new PrintJob(totalNumOfThreads);

/*
* MyRunnable runnable = new MyRunnable(printJob, 1); Thread t1 = new
* Thread(runnable);
*
* MyRunnable runnable2 = new MyRunnable(printJob, 2); Thread t2 = new
* Thread(runnable2);
*
* MyRunnable runnable3 = new MyRunnable(printJob, 3); Thread t3 = new
* Thread(runnable3);
*
* t1.start(); t2.start(); t3.start();
*/

// OR
ExecutorService executorService = Executors.newFixedThreadPool(totalNumOfThreads);
Set<Runnable> runnables = new HashSet<Runnable>();

for (int i = 1; i <= totalNumOfThreads; i++)
{
MyRunnable command = new MyRunnable(printJob, i);
runnables.add(command);
executorService.execute(command);
}

executorService.shutdown();
}
}

class MyRunnable implements Runnable
{

PrintJob printJob;
int threadNum;

public MyRunnable(PrintJob job, int threadNum)
{
this.printJob = job;
this.threadNum = threadNum;
}

@Override
public void run()
{
while (true)
{
synchronized (printJob)
{
if (threadNum == printJob.counter)
{
printJob.printStuff();

if (printJob.counter != printJob.totalNumOfThreads)
{
printJob.counter++;
} else
{

System.out.println();
// reset the counter
printJob.resetCounter();
}

printJob.notifyAll();

} else
{
try
{
printJob.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

}
}
}

class PrintJob
{
int counter = 1;
int totalNumOfThreads;

PrintJob(int totalNumOfThreads)
{
this.totalNumOfThreads = totalNumOfThreads;
}

public void printStuff()
{
System.out.println("Thread " + Thread.currentThread().getName() + " is printing");

try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}

public void resetCounter()
{
this.counter = 1;
}
}
Output
Thread pool-1-thread-1 is printing
Thread pool-1-thread-2 is printing
Thread pool-1-thread-3 is printing

Thread pool-1-thread-1 is printing
Thread pool-1-thread-2 is printing
Thread pool-1-thread-3 is printing

Thread pool-1-thread-1 is printing
Thread pool-1-thread-2 is printing
Thread pool-1-thread-3 is printing

Thread pool-1-thread-1 is printing
Thread pool-1-thread-2 is printing
Thread pool-1-thread-3 is printing

DelayQueueExample Example

· 2 min read
DelayQueueExample.java
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayQueueExample
{

public static void main(String[] args)
{

BlockingQueue<DelayedElement> blockingQueue = new DelayQueue<DelayedElement>();

try
{
blockingQueue.put(new DelayedElement(4000, "Message with delay 4s"));
blockingQueue.put(new DelayedElement(2000, "Message with delay 2s"));
blockingQueue.put(new DelayedElement(9000, "Message with delay 9s"));
} catch (InterruptedException ie)
{
}

while (!blockingQueue.isEmpty())
{
try
{
System.out.println(">>" + blockingQueue.take());
} catch (InterruptedException ie)
{
}
}
}
}

class DelayedElement implements Delayed
{

private long duration = 0;
private String message;

public DelayedElement(long duration, String name)
{
this.duration = System.currentTimeMillis() + duration;
this.message = name;
}

@Override
public int compareTo(Delayed o)
{

return (int) (this.duration - ((DelayedElement) o).getDuration());
}

/*
* Expiration occurs when an element's getDelay(TimeUnit unit) method
* returns a value less than or equal to zero.
*/
@Override
public long getDelay(TimeUnit unit)
{
long diff = duration - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}

public long getDuration()
{
return duration;
}

public void setDuration(long duration)
{
this.duration = duration;
}

public String getMessage()
{
return message;
}

public void setMessage(String message)
{
this.message = message;
}

@Override
public String toString()
{
return "DelayedElement [duration=" + duration + ", message=" + message + "]";
}
}
Output
>>DelayedElement [duration=1436431881725, message=Message with delay 2s]
>>DelayedElement [duration=1436431883725, message=Message with delay 4s]
>>DelayedElement [duration=1436431888725, message=Message with delay 9s]

ExecutorService InvokeAll Example

· One min read
ExecutorInvokeAllExample.java
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorInvokeAllExample
{

public static void main(String[] args) throws InterruptedException, ExecutionException
{
ExecutorService executorService = Executors.newSingleThreadExecutor();

Set<Callable<String>> callables = new HashSet<Callable<String>>();

callables.add(new CallableTask("Hello 1"));
callables.add(new CallableTask("Hello 2"));
callables.add(new CallableTask("Hello 3"));

List<Future<String>> futures = executorService.invokeAll(callables);

for (Future<String> future : futures)
{
System.out.println("future.get = " + future.get());
}
executorService.shutdown();
}
}

class CallableTask implements Callable<String>
{

String message;

public CallableTask(String message)
{
this.message = message;
}

@Override
public String call() throws Exception
{
return message;
}
}