问题1:
我正在阅读Java中的Hard-core多线程,并且确实进入了下面的信号量示例.
package com.dswgroup.conferences.borcon.threading; public class ResourceGovernor { private int count; private int max; public ResourceGovernor(int max) { count = 0; this.max = max; } public synchronized void getResource(int numberof) { while (true) { if ((count + numberof) <= max) { count += numberof; break; } try { wait(); } catch (Exception ignored) {} } } public synchronized void freeResource(int numberof) { count -= numberof; notifyAll(); } }
我觉得这可能导致以下情况陷入僵局:
正在使用所有资源,并且新线程会询问不可用的资源.由于它在synchronized函数内部等待,因此使用资源的其他线程无法释放资源,因为freeResource函数也被同步,并且由于等待线程已经取得对象级别锁定,它们无法进入该函数ResourceGovernor
还有另一个问题是,如果某个线程试图释放更多no,则尚未验证.资源比它获得的资源.但是这个问题是次要的,可以通过使用线程名称和资源计数的同步映射来轻松修复.
但我能否安全地说我正确诊断出第一个问题.(需要在embarcadero.com上发布很长一段时间后再次检查)
问题2:
我可以安全地说只有1个资源的信号量与互斥锁具有相同的行为吗?
正在使用所有资源,并且新线程会询问不可用的资源.由于它在synchronized函数内部等待,因此使用资源的其他线程无法释放资源,因为freeResource函数也被同步,并且由于等待线程已经取得对象级别锁定,它们无法进入该函数ResourceGovernor
你已经错过了通话的事实wait()
放弃监视器,以便其他同步代码是能够执行.来自以下文档wait()
:
当前线程必须拥有此对象的监视器.线程释放此监视器的所有权并等待,直到另一个线程通过调用
notify
方法或notifyAll
方法通知等待此对象的监视器上的线程唤醒.然后线程等待,直到它可以重新获得监视器的所有权并继续执行.
对于你的第二个问题:
我可以安全地说只有1个资源的信号量与互斥锁具有相同的行为吗?
我怀疑是这样,虽然你所展示的实现并没有让你freeResource
多次停止呼叫.这是在一个有点奇怪的实现我通常看到信号灯计算资源的数量剩余,而不是资源的数量采取的 -尽管他们是等价的,当然.