gpt4 book ai didi

java - Executor服务公平性

转载 作者:行者123 更新时间:2023-12-01 11:25:42 25 4
gpt4 key购买 nike

我有一个像这样的ExecutorService

ExecutorService executor =  new ThreadPoolExecutor(threads, threads,
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(1000, true));

我正在使用 .execute(Runnable) 向其发送工作

我的可运行程序有

        @Override
public void run() {
this.processor.performAction(this);
}

处理器所在位置

public void performAction(RunnableAction action) {
Lock lock = lockManager.getLock(action.getId());
lock.lock();
try {
action.execute();
} finally {
lock.unlock();
}
}

lockManager 在哪里

public class LockManager {

Map<String, Lock> lockById = new HashMap<>(1000);

public synchronized Lock getLock(String id) {
Lock lock = lockById.get(id);
if (lock == null) {
lock = new ReentrantLock(true);
}
return lock;
}

我的 actions/runnable 有一个 execQty 字段,该字段会触发某些调用其 order.execute(execQty) 的订单的更新

public void execute(int execQty) {
if (execQty < this.lastExecQty) {
System.err.println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
System.err.println("id: " + this.id + " wrong order" + this.lastExecQty + " > " + execQty);
}
this.execQty += execQty;
this.lastExecQty = execQty;
}
}

我已经命令我的可运行对象发送到调度程序,并且每个数量字段都比之前的大,因此在将每个可运行对象发送到 ExecutorService 之前打印每个可运行对象时,我总是得到我需要的、有序的数字:

execute: id: 49  qty: 819
execute: id: 49 qty: 820
execute: id: 49 qty: 821
execute: id: 49 qty: 822
execute: id: 49 qty: 823

但即使我的 ExecutorService 由公平队列支持,并且我在每个实体更新之前使用每个实体锁,它仍然似乎实体没有按顺序更新

execute: id: 88  qty: 6
execute: id: 88 qty: 7
execute: id: 88 qty: 8
execute: id: 88 qty: 9
execute: id: 88 qty: 10
execute: id: 88 qty: 11
execute: id: 88 qty: 12
execute: id: 88 qty: 13
execute: id: 88 qty: 14
execute: id: 88 qty: 15
execute: id: 88 qty: 16
execute: id: 88 qty: 17
execute: id: 88 qty: 18
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
id: 88 wrong order 17 (previous) > 7 (current)
execute: id: 88 qty: 19
execute: id: 88 qty: 20

仅使用一个线程运行 ExecutorService 时工作正常

最佳答案

您的 LockManager 似乎不正确。您永远不会将这些锁放入映射中,因此您始终在新对象上同步。

建议更改:

public synchronized Lock getLock(String id) {
Lock lock = lockById.get(id);
if (lock == null) {
lock = new ReentrantLock(true);
// put lock into the map so that next one will reuse it
lockById.put(id, lock);
}
return lock;
}

关于java - Executor服务公平性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30819396/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com