我一直在玩我自己的版本,使用'if',似乎一切正常.当然,如果使用signalAll()而不是signal(),这将会崩溃,但如果一次只通知一个线程,那怎么会出错呢?
他们的代码在这里 - 检查put()和take()方法; 可以在JavaDoc for Condition的顶部看到更简单,更多点的实现.
我的实施的相关部分如下.
public Object get() {
lock.lock();
try {
if( items.size() < 1 )
hasItems.await();
Object poppedValue = items.getLast();
items.removeLast();
hasSpace.signal();
return poppedValue;
} catch (InterruptedException e) {
e.printStackTrace();
return null;
} finally {
lock.unlock();
}
}
public void put(Object item) {
lock.lock();
try {
if( items.size() >= capacity )
hasSpace.await();
items.addFirst(item);
hasItems.signal();
return;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
PS我知道,一般来说,特别是在像这样的lib类中,应该让异常渗透.
我粘贴了下面的代码.这已经足够评论了.清除wait().来到这里时它跳到另一个街区.那部分我是橡木的.我怀疑的是为什么我们使用notify和notifyAll().如果从下面的代码中删除这两个,它可以正常工作.
class Reader extends Thread{
Calculator c;
//here we didn't write no-arg constructor. Note this.
// one - arg constructor.
public Reader(Calculator calc){
c = calc;
}
public void run(){
synchronized(c){
// 2. Acquiring the object lock and executes this code of block.
try{
System.out.println("Waiting for calculation...");
c.wait();
// 3. Release the object lock and moves to the second synchronize block below
// 6. Later the object get the lock here and moves on.
}catch(InterruptedException e){
}
System.out.println("Total is: "+c.total); …Run Code Online (Sandbox Code Playgroud)