java - ExecutorService fairness -
i have executorservice this
executorservice executor = new threadpoolexecutor(threads, threads, 0l, timeunit.milliseconds, new arrayblockingqueue<>(1000, true));
and i'm sending work .execute(runnable)
my runnable has
@override public void run() { this.processor.performaction(this); }
where processor has
public void performaction(runnableaction action) { lock lock = lockmanager.getlock(action.getid()); lock.lock(); try { action.execute(); } { lock.unlock(); } }
where lockmanager is
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; }
and actions/runnable have execqty field triggers update on orders calling 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; } }
i have ordered runnables send scheduler having qty field each bigger previous, when printing each runnable before sending executorservice need, ordered numbers:
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
but though executorservice backed fair queue, , i'm using per entity locks before each entity update still seems entity not updated in order
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
it works fine when running executorservice 1 thread
your lockmanager doesn't seem right. never putting locks map, synchronizing on new object.
suggested change:
public synchronized lock getlock(string id) { lock lock = lockbyid.get(id); if (lock == null) { lock = new reentrantlock(true); // put lock map next 1 reuse lockbyid.put(id, lock); } return lock; }
Comments
Post a Comment