java - 同步和信号量

标签 java multithreading synchronization semaphore

我正在循环遍历 Map ,并且我有许多线程。 映射中的队列包含操作。我的目标是给每个线程一个要执行的操作..但是没有 2 个线程(或更多)可以从一个队列运行 2 个任务(或更多) 这意味着每个线程都会搜索一个队列,并以某种方式锁定队列,并检查队列是否有操作,如果是,则运行其中一个,如果没有搜索另一个队列来运行它们的操作。 注意:队列数可以大于线程数 e 我尝试在“Map.Entry”上同步

        public void run() {

            while (true) {
                Action<?> act;
                for (Map.Entry entry :ActionMap.entrySet()) {
                   Synchronized(entry)
                   {
                      act =  ((Queue<Action>)entry.getValue()).poll();
                      if (act == null)
                        break;
                   }
                }

            }
            }  

问题是,如果另一个线程正在搜索要执行的操作,则会卡在同步行中并等待第一个线程完成任务或完成等待,这不是我想要的。 我希望所有线程搜索队列,如果某个线程到达另一个线程正在处理的队列,则跳过它并继续搜索

所以我四处挖掘并找到了信号量,所以我到达了这个

Semaphore Gate = new Semaphore(1);



        public void run() {

            while (true) {
                Action<?> act;
                for (Map.Entry entry :ActionMap.entrySet()) {
                   if( Gate.tryAcquire());
                   {
                      act =  ((Queue<Action>)entry.getValue()).poll();
                      if (act == null){
                    Gate.Release();
                    break;

                      }
                      else {
                      act.handle();
                      Gate.Release();
                    }
                   }
                }

            }
            }

问题在于 Gate.aquire() 将锁定所有条目 这意味着对于 2 个不同的条目和 2 个不同的线程,只有一个线程可以访问门并执行操作

那么最后有人有可以帮助我的设计模式吗? 谢谢...

最佳答案

您可以使用java.util.concurrent 类型的映射来实现此目的。它们是线程安全的,因此您不需要同步。

同步意味着:资源(已同步)不能同时被多个线程修改。例如,Collections.synchronizedMap(Map) 返回的 MAP 将是一个同步映射,一次可以由一个线程修改,但并发集合允许多个线程根据需要在给定时间访问集合的不同部分。例如,我们有一个 ConcurentHashMap 的重载构造函数,它将输入 concurrencyLevel 作为可以同时访问集合的线程数。

关于java - 同步和信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47700102/

相关文章:

Python:多线程设置一次变量

java - 将多个回调处理到一个接收器函数中的最有效方法

java - 为什么此代码中没有发生同步?

go - 使用同步/原子包进行同步的代码中的意外行为

java - 删除 JTable 中的单元格编辑器边框 (Windows LaF)

java - 使用 GDX NET api 时出现 JVM 绑定(bind)错误

java - 如何使用 Envers 审核 Hibernate 读取?

Java While 循环

c# - 如何优化读取访问?

c++ - cpp 中的线程给出错误