java - 如果我们无论如何都要同步函数,为什么还需要信号量

标签 java multithreading

以下代码是我从 Semaphore 上的 Oracle 文档中获取的。

我的问题是,如果我同步 getNextAvailableItem() 和 markAsUnused 方法,这将阻止其他 99 个线程进入主函数,该函数要么给我共享资源,要么接受它返回。那么信号量有什么用无论是 99 个还是 1000 个线程正在等待锁都没有关系。

 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; 
    }
       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;
    }
   }

最佳答案

问题是:您是否希望线程阻塞直到有可用的项目?

如果是,那么信号量是必要的,因为它基本上是一个计数器,当它已经为零并且线程试图获取它时会阻塞。

显然,您可以尝试在不使用信号量的情况下在同步方法中自己实现这一点(即使用一些低级结构,例如 wait/notify),但这只是一个邀请很难发现的错误。

如果不需要阻塞,并且您喜欢该方法向调用者返回 null,那么您可以跳过信号量。

关于java - 如果我们无论如何都要同步函数,为什么还需要信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25825596/

相关文章:

java - 指定二进制转换的位数

java - Java中的关键字 'of'

java - 具有良好插入、移除和随机访问能力的数据结构

java - JRebel 与 IntelliJ - 热插拔

c# - 从静态方法线程安全返回引用吗?

java - 多线程socket通信场景

android - 等待信号量循环时的 SystemClock.sleep() 与 Thread.sleep()

java - 如何在 android 中使用 DateFormat.getDateTimeInstance() 仅显示当前时间

iphone - 辅助线程的堆栈大小,DEBUG 和 RELEASE 版本之间的显着差异

c++ - 在弹出窗口中管理 CEF 客户区的窗口消息