Java 为什么在使用同步时使用信号量?
我正在阅读关于信号量的内容,在代码示例中,它让我困惑,为什么在代码对最终调用的方法使用同步化时使用信号量。这不是在做同样的事情吗,即一次限制一个线程来执行变异Java 为什么在使用同步时使用信号量?,java,synchronization,semaphore,Java,Synchronization,Semaphore,我正在阅读关于信号量的内容,在代码示例中,它让我困惑,为什么在代码对最终调用的方法使用同步化时使用信号量。这不是在做同样的事情吗,即一次限制一个线程来执行变异 class Pool { private static final int MAX_AVAILABLE = 100; private final Semaphore available = new Semaphore(MAX_AVAILABLE, true); public Object getItem() throw
class Pool {
private static final int MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
public void putItem(Object x) {
if (markAsUnused(x))
available.release();
}
// Not a particularly efficient data structure; just for demo
protected Object[] items = ... whatever kinds of items being managed
protected boolean[] used = new boolean[MAX_AVAILABLE];
protected synchronized Object getNextAvailableItem() {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (!used[i]) {
used[i] = true;
return items[i];
}
}
return null; // not reached
}
protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
} else
return false;
}
}
return false;
}
}
类池{
专用静态最终int MAX_可用=100;
专用最终可用信号量=新信号量(最大可用信号量,true);
公共对象getItem()引发InterruptedException{
可用。获取();
返回getNextAvailableItem();
}
公共项目(对象x){
如果(使用标记(x))
可用。释放();
}
//不是特别有效的数据结构;只是为了演示
受保护对象[]项=…管理的任何类型的项
受保护的布尔值[]已使用=新的布尔值[MAX_AVAILABLE];
受保护的同步对象getNextAvailableItem(){
对于(int i=0;i
我指的是对getItem()的调用,它调用acquire(),然后调用getNextAvailableItem,但无论如何都是同步的
我错过了什么
参考:一个
信号量
为您提供了一个线程安全计数器,当调用acquire
超过初始限制时,该计数器将被阻塞<代码>释放可用于撤消获取
它将保证如果调用acquire
成功,则有足够的容量容纳新项目
在这个示例中,有一些循环查找空闲项。使用信号灯
可以确保在有可用项之前,这些循环都不会开始
synchronized
只保证一个线程一次只能执行这段代码。信号量和同步块执行两个不同的任务
- synchronized关键字在访问和更改项数组时保护getNextAvailableItem()。如果一次不限于一个线程,则会损坏的操作
- 信号量将允许多达100个线程通过,明显多于1个。在这个代码示例中,它的目的是在池为空时阻止对池中对象的请求,然后在对象返回池时取消阻止一个线程。没有信号灯,事情看起来就像是在工作,直到池是空的。此时,请求线程不会阻塞并等待对象返回,而是接收null