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


信号量管理生产的最大项目数