Java 信号量函数中的死锁
问题1: 我在阅读时遇到了下面的信号量示例Java 信号量函数中的死锁,java,multithreading,Java,Multithreading,问题1: 我在阅读时遇到了下面的信号量示例 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
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();
}
}
package com.dswgroup.conferences.borcon.threading;
公共类资源管理器{
私人整数计数;
私人int max;
公共资源管理器(int max){
计数=0;
this.max=max;
}
公共同步的void getResource(int numberof){
while(true){
如果((计数+数字)
所有资源都在使用中,一个新线程请求不可用的资源。由于它在同步函数内等待,使用这些资源的其他线程无法释放资源,因为freeResource函数也在同步中,并且由于等待的线程已执行oResourceGovernor的对象级别锁
您没有注意到调用wait()
会放弃监视器,因此可以执行其他同步代码。来自以下文档:
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify
方法或notifyAll
方法通知等待此对象监视器的线程唤醒。然后线程等待,直到它可以重新获得m的所有权监视并恢复执行
关于第二个问题:
我可以安全地说,只有1个资源的信号量具有与互斥锁相同的行为吗
我怀疑是这样,尽管您所展示的实现实际上并没有阻止您多次调用freereresource
。这是一个有点奇怪的实现,因为我通常看到信号量计算剩余资源的数量,而不是占用的资源的数量——当然,它们是等效的
所有资源都在使用中,一个新线程请求不可用的资源。由于它在同步函数内等待,使用这些资源的其他线程无法释放资源,因为freeResource函数也在同步中,并且由于等待的线程已执行oResourceGovernor的对象级别锁
您没有注意到调用wait()
会放弃监视器,因此可以执行其他同步代码。来自以下文档:
当前线程必须拥有此对象的监视器。线程释放此监视器的所有权并等待,直到另一个线程通过调用notify
方法或notifyAll
方法通知等待此对象监视器的线程唤醒。然后线程等待,直到它可以重新获得m的所有权监视并恢复执行
关于第二个问题:
我可以安全地说,只有1个资源的信号量具有与互斥锁相同的行为吗
我想是这样的,尽管您所展示的实现实际上并没有阻止您多次调用freeResource
。这是一个有点奇怪的实现,因为我通常看到信号量计算剩余资源的数量,而不是占用的资源的数量——当然,它们是等效的。问题2:是的,它类似于互斥。但是,尽管互斥和信号量在其实现中有相似之处,但它们的使用应该总是不同的。问题2:是的,它类似于互斥。但是,尽管互斥和信号量在其实现中有相似之处,但它们的使用应该总是不同的。您给我的验证问题ntioned可能是故意的。例如,JDK的信号灯类声明“不要求发布许可证的线程必须通过调用acquire来获取该许可证。”创建没有许可证的信号灯,让一个线程尝试获取许可证,然后让另一个线程“释放”许可证是完全合法的这样,信号量也可以模拟倒计时锁存器(类似于二进制信号量-1-permit-可以模拟互斥锁存器的方式)。请记住,这篇文章是2004年的。它的所有内容今天都被弃用。要获得更好的解决方案,请查看并发包。您提到的验证问题可能是有意为之。例如,JDK的信号量类声明“不要求发布许可证的线程必须通过调用acquire获得该许可证。”完全可以在没有许可证的情况下创建信号量,让一个线程尝试获取许可证,然后让另一个线程“发布”许可证(一开始从未获得过许可证)。通过这种方式,信号量也可以模拟倒计时锁存器(类似于二进制信号量-1许可证-可以模拟互斥)。请记住,这篇文章是从2004年开始的。它的所有内容今天都被弃用。要获得更好的解决方案,请查看并发包。