multithreading - Interthread communication in Java -
i have 2 java threads need talk each other , i'm not sure i'm going right way.
the basic this: have on thread, "runner" start off long-running process making call command line using the apache exec library. thread, "monitor", periodically monitor , report on state of system.
part of involves returning lines runner process got stdout. currently, runner , monitor run separate threads. monitor has reference runner , can access output collected (so far) calling runner's "get stdout" method.
this seems working fine, whole setup doesn't seem me. partly, i'm worried implementation isn't thread-safe, though i'm not sure how test that. it's been quite while since i've done multithreaded programming, i'm wondering if there's better/cleaner way i'm trying do. code looks this:
public class runner implements callable<string> { private bytearrayoutputstream outputstream = new bytearrayoutputstream(); private bytearrayoutputstream errorstream = new bytearrayoutputstream(); public string getstdoutlines() { return new string(outputstream.tobytearray()); } public string getstderrlines() { return new string(errorstream.tobytearray()); } @override public string call() throws exception { /* use apache exec begin long-running process. stdout , stderr written 2 local members (outputstream , errorstream). done apache exec library. */ pumpstreamhandler streamhandler = new pumpstreamhandler(this.outputstream, this.errorstream); defaultexecuteresulthandler resulthandler = new defaultexecuteresulthandler(); executor.setstreamhandler(streamhandler); commandline cli = //details not important here. executor.execute(cli, resulthandler); resulthandler.waitfor(); string resultsstring = generatefinalresultstring(outputstream, errorstream); //implementation details of not important here. return resultsstring; /*some string calculated after process has completed.*/ } } public class monitor implements runnable { private runner runner; public void setrunner(runner r) { this.runner = r; } @override public void run() { try { while (!thread.currentthread().interrupted()) { //call functions on other thread stdout , stderr commandstdout = this.runner.getstdoutlines(); commandstderr = this.runner.getstderrlines(); dosendmonitoringmessage(commandstdout, commandstderr); thread.sleep(some_delay); } } catch(interruptedexception e) { system.out.println("monitor shutting down"); } } } public class executeallthis { public void dothestuff() { system.out.println("begining..."); runner runner = new runner(); monitor monitor = new monitor(); monitor.setrunner(runner); executorservice xservice = executors.newfixedthreadpool(2); xservice.execute(monitor); future<string> runnerfuture = xservice.submit(runner); string result = runnerfuture.get(0); system.out.println("result is: "+result); }
edit: i've added detail how i'm calling long-running process writes stdout , stderr strings, since more relevant realized.
your implementation fine.
however, in theory, variables outputstream
, errorstream
should volatile
, otherwise possible monitor thread not latest updates - in theory.
another reason using volatile
shared variables, in general case, prevent reading corrupt states. reason not apply here though since string
immutable.
another advice, if not sure, use old synchronized
. might little slower volatile
, not problem; , not in case.
Comments
Post a Comment