我正在尝试理解Java多线程构造,我正在尝试编写阻塞队列的简单实现。这是我写的代码:
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;
}
我想通过put()通知在Take()中等待的线程,反之亦然。有人可以帮助我正确的方法来做到这一点。
我检查了java.utils实现,它使用了Condition和ReentrantLocks,这对我来说有点复杂。为了简单起见,我现在没有完全健壮[但是正确]。
谢谢!
答案 0 :(得分:2)
答案很简单,请致电notifyAll()
,其中包含评论//How to notify threads waiting during take()
现在有更完整的答案......
的读取参考是:Java Concurrency in Practice。你问题的答案就在那里。
但是,简要回答一下您的问题:在Java中,线程通过锁定同一对象并使用wait()
和notify()
来安全地更改状态来进行同步。典型的简化流程为:
synchronized
块来获取锁定thread.wait()
,这是一个“释放”锁定的阻塞调用,以便在同一个锁定对象上同步的其他代码可以继续notifyAll()
时,线程A将被唤醒并重新检查条件并且(可能)继续有关同步的一些注意事项是:
wait
和notify
关于相同的“主题” 。国家的每个部分都应该由自己的锁定对象保护 - 通常是私人领域,例如private Object lock = new Object();
没问题this
作为锁定对象 - 这样做很容易,但可能很昂贵,因为您锁定每次调用,而不是仅在需要时