java - Controlling thread using wait() and notify() -
(problem solved, solution below)
have 2 classes: equip , command. equip equipment run commands, need able run 1 command @ same time. command thread, executes on run() function, while equip normal class don't extend anything. have following setup run commands:
command class:
@override public void run() { boolean execute = equip.queuecommand(this); if (!execute) { // if command 1 on queue, execute it, or wait. esperar(); } // executes command..... equip.executenextcommand(); } synchronized public void esperar() { try { this.wait(); } catch (exception ex) { log.logerro(ex); } } synchronized public void continue() { this.notifyall(); }
equip class:
public boolean queuecommand(command cmd) { // commandqueue linkedlist commandqueue.addlast(cmd); return (commandqueue.size() == 1); } public void executenextcommand() { if (commandqueue.size() >= 1) { command cmd = commandqueue.pollfirst(); cmd.continue(); } }
however, not working. basically, notify() isn't waking command thread, it'll never execute. searched wait , notify protocol, couldn't find wrong code. tried calling wait() directly queuecommand() method, execution of queuecommand stopped, , didn't supposed do. approach correct , i'm missing or wrong , should implement monitor class manipulate concurrent threads?
edit: solved problem using different approach, using executors, @gray.
here's final code, might someday:
equip class:
private executorcompletionservice commandqueue = new executorcompletionservice(executors.newfixedthreadpool(1));
public void executecommand(command cmd, boolean waitcompletion) { commandqueue.submit(cmd, null); if (waitcompletion) { try { commandqueue.take(); } catch (exception ex) { } } }
in command class have method encapsulate equip's execute method. boolean waitcompletion used when need result of command @ same time, , instead of calling new thread execute it, execute , wait, pretending it's executing on same thread. question contains discussion on matter: when call java's thread.run() instead of thread.start()?. , yes, case it's useful call .run() instead of .start().
there large number of race conditions exist in code if command.run()
called multiple threads. unless sort of homework question have implement code yourself, highly recommend using 1 of java executors
added in 1.6. in case executors.newsinglethreadexecutor()
need limit number of running background tasks 1. allow unlimited number of tasks submitted executorservice
, 1 of tasks executing @ 1 time.
if need thread submitting tasks block when task running use following. sets pool of maximum of 1 thread , uses synchronousqueue
blocks until worker thread consumes job:
final executorservice executorserver = new threadpoolexecutor(0, 1, 60l, timeunit.seconds, new synchronousqueue<runnable>());
but if case call task directly inside of synchronized
block , wouldn't need executorservice
.
lastly, new concurrency programmer (of language) recommend take time read documentation on subject. until start recognizing concurrent pitfalls inherent in threading simplest set of classes, frustrating process code work. doug lea's book 1 of bible's on subject. apologies if have underestimated experience in area.
Comments
Post a Comment