Java finally子句中的信号量操作

Java finally子句中的信号量操作,java,concurrency,semaphore,Java,Concurrency,Semaphore,我正在实践中阅读Java并发 公共类BoundedHashSet{ 私有最终集; 私有最终信号量; 公共绑定哈希集(int绑定){ this.set=Collections.synchronizedSet(新HashSet()); sem=新信号量(绑定); } 公共布尔加法(TO)抛出InterruptedException{ sem.acquire(); 布尔值wasAdded=false; 试一试{ wasAdded=set.add(o); 增加了回报率; }最后{ 如果(!已添加) se

我正在实践中阅读Java并发

公共类BoundedHashSet{
私有最终集;
私有最终信号量;
公共绑定哈希集(int绑定){
this.set=Collections.synchronizedSet(新HashSet());
sem=新信号量(绑定);
}
公共布尔加法(TO)抛出InterruptedException{
sem.acquire();
布尔值wasAdded=false;
试一试{
wasAdded=set.add(o);
增加了回报率;
}最后{
如果(!已添加)
sem.release();
}
}
公共布尔删除(对象o){
布尔值wasRemoved=set.remove(o);
如果(已删除)
sem.release();
取消退货;
}
}
我不知道为什么
add
方法有try finally子句而
remove
方法没有。 我认为可以像下面这样简化它

public boolean add(to)抛出InterruptedException{
sem.acquire();
布尔值wasAdded=set.add(o);
如果(!已添加)
sem.release();
增加了回报率;
}

放置try finally而不是简单语句的好处是什么?

TL:DR:对的调用可能在获得许可证后引发异常


在这种情况下,
信号量的许可表示容量。添加元素时,将获取一个许可证,然后尝试将该元素添加到内部
集合
。然后检查调用
add
的结果,以确保实际添加了元素。如果未添加元素,则必须释放先前获得的许可。到目前为止一切都很好

问题是它可能引发异常。在这种情况下,获得的许可证仍必须发放。try finally块保证,如果由于不允许重复或抛出异常而未添加元素,则先前获取的许可证将被释放

public boolean add(to)抛出InterruptedException{
sem.acquire();//在尝试添加元素之前获取的许可证
布尔值wasAdded=false;
试一试{
wasAdded=set.add(o);
增加了回报率;
}最后{
如果(!已添加)
sem.release();//如果“set.add(o)”返回false**或**抛出异常,则调用
}
}
由于您的版本没有try finally块,因此代码被破坏:

public boolean add(to)抛出InterruptedException{
sem.acquire();//在尝试添加元素之前获取的许可证
boolean wasAdded=set.add(o);//若引发异常,则永远不会释放许可证
如果(!已添加)
sem.release();//仅当“set.add(o)”返回false时调用
增加了回报率;
}
删除元素不会出现相同的问题。在试图移除元件之前,未发布任何许可证,因此,如果元件未实际移除,则无需重新获取许可证。即使抛出异常,情况仍然如此

公共布尔删除(对象o){
布尔值wasRemoved=set.remove(o);
如果(已删除)
sem.release();//如果“set.remove(o)”返回false或引发异常,则不会调用
取消退货;
}