【问题标题】:List of Semaphores in Java and concurrencyJava中的信号量列表和并发
【发布时间】:2020-11-17 01:28:55
【问题描述】:

我有一个应用程序,在我的实现中我需要一些信号量。我的问题是这如何与 ArrayList 一起使用?

假设我有一个包含多个信号量的ArrayList<Semaphore> semList;,如果我执行 semList.get(0).aquire();信号量是否会在列表中相应更新 - 换句话说,其他线程会知道它已被获取吗?我不确定,因为 ArrayList.get() 只获得对对象的引用。

【问题讨论】:

  • 作为对象的变量总是对对象的引用。
  • @NathanHughes 你对解决方案有什么建议吗?
  • Vector 是线程安全的,CopyOnWriteArrayList 也是如此。
  • @Turing85 我已经查看了 CopyOnWriteArrayList,但我打算在这里使用信号量。当下一个线程从列表中获取时,不需要获取获取的信号量还是我错了?
  • Re,“这将像我打算在这里那样与信号量一起工作吗?” CopyOnWriteArrayListVector 或任何其他类型的容器的工作方式完全独立于您放入容器中的内容。同样,Semaphore 的工作方式与您碰巧在哪里找到它的引用完全无关。

标签: java multithreading arraylist concurrency semaphore


【解决方案1】:

“列表中的信号量是否会相应更新”?

这样想:信号量不在列表中,列表中只存储了对信号量的引用。如果另一个线程调用get(0),它将获得对相同信号量的引用(除非列表已被修改,或者存在数据竞争)。所以是的,其他线程会知道它已被获取。

如果您同时修改列表,那么您应该使用线程安全列表,但如果它被初始化并填充一次,然后没有更改并安全地发布到其他线程,那么您可以使用 ArrayList。

我建议阅读有关内存模型的 JLS 部分以帮助更好地理解它:https://docs.oracle.com/javase/specs/jls/se14/html/jls-17.html#jls-17.4.5

【讨论】:

    【解决方案2】:

    信号量是否会在列表中相应更新

    是的,无论您是直接引用信号量还是通过 list.get(0) 引用信号量都没有关系。所有线程都访问同一个实例。假设信号量还剩一个许可,调用acquire 方法的下一个线程将获得最后一个许可。下一个线程将一直等待,直到许可被释放。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2020-02-01
      • 2023-03-11
      相关资源
      最近更新 更多