Sequential Producer & Consumer
In my first example, I will demonstrate an implementation to solve the famous producer and consumer problem. Producer should complete its production, before Consumer can consume it, as simple as that. In addition, both the operations should run on 2 separate threads.
public class SequentialExecutor {
/**
* Shared
*/
volatile int shared;
/**
* Lock object, whose monitor will be shared by both the threads
*/
Object lock = new Object();
/**
* Producer
*/
P p;
/**
* Consumer
*/
C c;
public SequentialExecutor(){
p = new P();
c = new C();
}
public class P implements Runnable {
public void run(){
while(true){
synchronized (lock) {
try{
// add some processing delay
Thread.sleep(1000);
}catch(Exception ex){
ex.printStackTrace();
}
shared++;
System.out.println("Produce->"+ shared);
}
}
}
}
public class C implements Runnable {
public void run(){
while(true){
synchronized (lock) {
try{
// add some processing delay
Thread.sleep(1500);
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println("Consume->"+ shared);
}
}
}
}
public static void main(String[] args){
SequentialExecutor se = new SequentialExecutor();
new Thread(se.p, "P Thread").start();
new Thread(se.c, "C Thread").start();
}
}
You’ll get output as-
Produce->1
Consume->1
Produce->2
Consume->2
Produce->3
Consume->3
Produce->4
Consume->4
Here the trick is being done by the common object
lock.Binary Semaphore Implementation
public class Semaphore {
int counter = 0;
/**
* Binary Semaphore- restricts the probable counter values
* to (0/1)
*/
int BOUND = 1;
/**
* Acquire the lock.
* This SHOULD be an Atomic operation
*/
public synchronized void acquire(){
Thread currentThread = Thread.currentThread();
System.out.println("[acquire] Thread: "+ currentThread.getName()+" - Start");
System.out.println("Counter: "+ counter);
while(counter == BOUND){
// make the calling thread wait
System.out.println(currentThread.getName()+ " Waiting to Acquire...");
try{
wait();
}catch(Exception ex){
ex.printStackTrace();
}
}
counter++;
System.out.println("[acquire] Thread: "+ currentThread.getName()+" -Done");
}
/**
* Release the lock.
* This SHOULD be an Atomic operation
*/
public synchronized void release(){
Thread currentThread = Thread.currentThread();
System.out.println("[release] Thread: "+ currentThread.getName());
System.out.println("Counter: "+ counter);
if(counter > 0){
counter--;
try{
// Notify the other thread waiting to acquire lock
notify();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
}
How to use it-
Acquire
the Semaphore lock-
acquire()Do some operation.
Release
the Semaphore lock. (Make sure you release it. Otherwise, other threads will never get chance to execute)-
release()
Comments
Post a Comment