We have the some ways to communicate in between threads.
All of usknow that "wait" and "notify", which is a traditional method of communicating.
With the introduction of Locks and Condition , we have better performance and control .
It was already proved that Locks and Conditions are more throughput than Synchronized blocks.
Here I will try to explain the simple producer - consumer problem without Locks and Condition.
package org.ohms.threads.locks;
import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* Producer Consumer Problem...Solved with Locks
*
* @author
*
*/
public class PCproblemWithLocks {
private static int storedBox=-1;;
public static void main(String[] args) throws InterruptedException {
int totalProduction=1000;
Lock lock=new ReentrantLock();
Condition condition= lock.newCondition();
Buffer buffer= new Buffer();
Thread producer= new Thread(new Producer(totalProduction, buffer,lock,condition));
Thread consumer= new Thread(new Consumer(totalProduction, buffer,lock,condition));
System.out.println("=====================================");
producer.start();
consumer.start();
producer.join();
consumer.join();
System.out.println("Completed .....");
}
/**
* used to store the values or a common
* object where two threads used.
*
* @author
*
*/
static class Buffer {
void put(int newValue)
{
storedBox = newValue;
}
int get()
{
return storedBox;
}
void clear() {
storedBox=-1;
}
}
/**
* Used to store the Value
* in the StoredBox(int variable defined above)
*
* @author
*
*/
static class Producer implements Runnable
{
private int counter;
private Buffer buffer;
private Lock lock;
private Condition condition;
public Producer(int count,Buffer buffer,Lock lock,Condition condition)
{
this.counter=count;
this.buffer=buffer;
this.lock=lock;
this.condition=condition;
System.out.println("Producer Started placing the Values");
}
@Override
public void run()
{
try {
this.lock.lock();
System.out.println(" Producer Lock Acquired ");
for (int i = 0; i < this.counter; i++)
{
if(this.buffer.get()!=-1)
{
//System.out.println("Waiting to put>>>>>>");
condition.await();
System.out.println(" Producer Lock Acquired ");
}
int randomValue=i;//new Random().nextInt(100);
this.buffer.put(randomValue);
System.out.println("Produced -->"+randomValue);
condition.signalAll();
System.out.println(" Producer Lock Released ");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
this.lock.unlock();
}
}
}
/**
* used to retrieve/read the stored value
* in the StoredValue Box
*
* @author Kumar
*
*/
static class Consumer implements Runnable {
private int counter;
private Buffer buffer;
private Lock lock;
private Condition condition;
public Consumer(int count,Buffer buffer,Lock lock,Condition condition) {
this.counter=count;
this.buffer=buffer;
this.lock=lock;
this.condition=condition;
System.out.println("Consumer started Reading the Values ");
}
@Override
public void run()
{
this.lock.lock();
System.out.println(" Consumer Lock Acquired ");
try {
for (int i = 0; i < this.counter; i++)
{
if(this.buffer.get()==-1)
{
//System.out.println("Waiting to get <<<<<<<<<<");
condition.await();
System.out.println(" Consumer Lock Acquired ");
}
System.out.println("Consumed -->"+this.buffer.get());
this.buffer.clear();
condition.signalAll();
System.out.println(" Consumer Lock Released ");
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
this.lock.unlock();
}
}
}
}
run the above program to know the usage of the Locks and condition in java .