我正在循环遍历 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/