Reputation: 6647
I am trying to understand Java multi-threading constructs, and I am trying to write a simple implementation of blocking queue. Here is the code I have written:
class BlockingBoundedQueue<E>
{
@SuppressWarnings("unchecked")
BlockingBoundedQueue(int size)
{
fSize = size;
fArray = (E[]) new Object[size];
// fBlockingQueue = new ArrayBlockingQueue<E>(size);
}
BlockingQueue<E> fBlockingQueue;
public synchronized void put(E elem)
{
if(fCnt==fSize-1)
{
try
{
// Should I be waiting/locking on the shared array instead ? how ?
wait();
}
catch (InterruptedException e)
{
throw new RuntimeException("Waiting thread was interrupted during put with msg:",e);
}
}
else
{
fArray[fCnt++]=elem;
//How to notify threads waiting during take()
}
}
public synchronized E take()
{
if(fCnt==0)
{
try
{
// Should I be waiting/locking on the shared array instead ? how ?
wait();
}
catch (InterruptedException e)
{
throw new RuntimeException("Waiting thread was interrupted during take with msg:",e);
}
}
return fArray[fCnt--];
//How to notify threads waiting during put()
}
private int fCnt;
private int fSize;
private E[] fArray;
}
I want to notify threads waiting in Take() from put() and vice versa. Can someone please help me with the correct way of doing this.
I checked the java.utils implementation and it uses Condition and ReentrantLocks which are a little complex for me at this stage. I am okay of not being completely robust[but correct] for the sake of simplicity for now.
Thanks !
Upvotes: 2
Views: 5023
Reputation: 425033
The short answer is, call notifyAll()
where you have the comments //How to notify threads waiting during take()
Now for the more complete answer...
The reference to read is : Java Concurrency in Practice. The answer to your question is in there.
However, to briefly answer your question: in Java, threads synchronize by locking on the same object and using wait()
and notify()
to safely change state. The typical simplified flow is:
synchronized
block on a lock objectthread.wait()
, which is a blocking call that "releases" the lock so other code synchronized on the same lock object can proceednotifyAll()
, thread A will wake up and recheck the condition and (may) proceedSome things to remember about synchronization are:
wait
and notify
about the same "subject". Each part of state should be guarded by its own lock object - usually a private field, e.g. private Object lock = new Object();
would be finethis
as the lock object - doing this is easy but potentially expensive, because you are locking for every call, instead of just when you need toUpvotes: 2