У меня есть ExecutorService как этот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;
}
и мои действия/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;
}
}
Я заказал мои runnables отправить в планировщик всегда имея QTY поле каждый больше, чем предыдущий, поэтому при печати каждой работоспособной перед его отправкой в 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 с только одна нить