Skip to content

Instantly share code, notes, and snippets.

@sandeepkunkunuru
Last active December 20, 2015 12:39
Show Gist options
  • Save sandeepkunkunuru/6132857 to your computer and use it in GitHub Desktop.
Save sandeepkunkunuru/6132857 to your computer and use it in GitHub Desktop.
Java Multi-Threaded Programming : Simple Illustration using join, wait, notify
=============================================================================
Sample Output: with leastQueueSize and maxQueueSize as 1 and maximumJobs as 5
=============================================================================
This will always get printed at the very start
Thread-1-101
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 1
Thread-2-101
Thread-2 is notifying other threads to wake up
Thread-2 is going to wait state since queue size is 0
Thread-1-589
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 1
Thread-2-589
Thread-2 is notifying other threads to wake up
Thread-2 is going to wait state since queue size is 0
Thread-1-708
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 1
Thread-2-708
Thread-2 is notifying other threads to wake up
Thread-2 is going to wait state since queue size is 0
Thread-1-436
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 1
Thread-2-436
Thread-2 is notifying other threads to wake up
Thread-2 is going to wait state since queue size is 0
Thread-1-325
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 1
Thread-2-325
Thread-2 is notifying other threads to wake up
Thread-2 is going to wait state since queue size is 0
Thread-1-642
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 1
Thread-2-642
Thread-2 is notifying other threads to wake up
This will always get printed at the very end
======================
==================================================================================
Sample Output: with leastQueueSize as 1 and maxQueueSize as 3 and maximumJobs as 5
==================================================================================
This will always get printed at the very start
Thread-1-566
Thread-1 is notifying other threads to wake up
Thread-1-589
Thread-1 is notifying other threads to wake up
Thread-1-587
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 3
Thread-2-566
Thread-2 is notifying other threads to wake up
Thread-2-589
Thread-2 is notifying other threads to wake up
Thread-2-587
Thread-2 is notifying other threads to wake up
Thread-2 is going to wait state since queue size is 0
Thread-1-781
Thread-1 is notifying other threads to wake up
Thread-1-340
Thread-1 is notifying other threads to wake up
Thread-1-989
Thread-1 is notifying other threads to wake up
Thread-1 is going to wait state since queue size is 3
Thread-2-781
Thread-2 is notifying other threads to wake up
Thread-2-340
Thread-2 is notifying other threads to wake up
Thread-2-989
Thread-2 is notifying other threads to wake up
This will always get printed at the very end
=====================
package me.tingri.design.threads;
import java.util.LinkedList;
import java.util.Queue;
public class ThreadIllustration {
/**
* @param args
*/
public static void main(String[] args) {
Monitor<Integer> monitor;
if (args.length == 3) {
monitor = new Monitor<Integer>(Integer.parseInt(args[0]), Integer.parseInt(args[1]), Integer.parseInt(args[2]));
} else {
monitor = new Monitor<Integer>();
}
Thread controller = new Thread(new Controller(monitor));
controller.start();
}
private static class Monitor<T> {
private Queue<T> jobQueue = new LinkedList<T>();
private int counter;
private int leastQueueSize;
private int maxQueueSize;
Monitor() {
this.leastQueueSize = 1;
this.maxQueueSize = 1;
this.counter = 5;
}
// if maximum jobs isn't a multiple of max queue size then some jobs will be left out in the queue
Monitor(int leastQueueSize, int maxQueueSize, int maximumJobs) {
this.leastQueueSize = leastQueueSize;
this.maxQueueSize = maxQueueSize;
this.counter = maximumJobs;
}
boolean hasSufficientQueue() {
return jobQueue.size() >= leastQueueSize;
}
boolean reachedQueueSizeLimit() {
return jobQueue.size() == maxQueueSize;
}
public void add(T value) {
jobQueue.add(value);
}
public T remove() {
counter--;
return jobQueue.remove();
}
public boolean stop(){
return counter < 0;
}
}
private static class Controller implements Runnable {
private Monitor monitor;
public Controller(Monitor monitor) {
this.monitor = monitor;
}
public void run() {
try {
Thread producer = new Thread(new Producer(monitor));
Thread consumer = new Thread( new Consumer(monitor));
System.out.println("This will always get printed at the very start");
producer.start();
consumer.start();
//If t is a Thread object whose thread is currently executing,
// t.join();
// causes the current thread to pause execution until t's thread terminates.
//Like sleep, join responds to an interrupt by exiting with an InterruptedException.
producer.join();//Controller waits till producer is terminated
consumer.join();//Controller waits till consumer is also terminated
System.out.println("This will always get printed at the very end");
} catch (InterruptedException ie) {
System.out.println("Controller has been interrupted");
}
}
}
private static class Producer implements Runnable {
private final Monitor monitor;
public Producer(Monitor monitor) {
this.monitor = monitor;
}
public void run() {
try {
while (true) {
synchronized (monitor) {
if(monitor.stop()){
break;
} else if (!monitor.reachedQueueSizeLimit()) {
int value = (int) Math.floor(Math.random() * 1000);
monitor.add(value);
System.out.println(Thread.currentThread().getName() + "-" + value);
System.out.println(Thread.currentThread().getName() + " is notifying other threads to wake up");
monitor.notify();
} else {
System.out.println(Thread.currentThread().getName() + " is going to wait state since queue size is " + monitor.jobQueue.size());
monitor.wait();
}
}
}
} catch (InterruptedException ie) {
System.out.println("Producer has been interrupted");
}
}
}
private static class Consumer implements Runnable {
private final Monitor monitor;
public Consumer(Monitor monitor) {
this.monitor = monitor;
}
public void run() {
try {
while (true) {
synchronized (monitor) {
if(monitor.stop()){
break;
} else if (!monitor.hasSufficientQueue()) {
System.out.println(Thread.currentThread().getName() + " is going to wait state since queue size is " + monitor.jobQueue.size());
monitor.wait();
} else {
System.out.println(Thread.currentThread().getName() + "-" + monitor.remove());
System.out.println(Thread.currentThread().getName() + " is notifying other threads to wake up");
monitor.notify();
}
}
}
} catch (InterruptedException ie) {
System.out.println("consumer has been interrupted");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment