multithreading - Java Interthread Communication not passing message object -
to communicate between threads, followed oracle guarded blocks example, readily compiles , runs. architecture different, consumer spawns producer task, though tried variation example , works perfectly.
the pertinent code main program;
public static void main(string[] args) { ... framemsg framemsg = new framemsg(); awarenessanalytics awarenessanalytic = new awarenessanalytics(framemsg); awarenessanalytic.start();
the pertinent code consumer thread;
public class awarenessanalytics extends thread implements motioneventlistener{ framemsg framemsg; framewithmotiondetection framewithmotiondetection; public awarenessanalytics(framemsg framemsg) { this.framemsg = framemsg; system.out.println("awarenessanalytic framemsg = " + this.framemsg.hashcode()); } advancedvideoanalytics tempintermediateva; tempintermediateva = new advancedvideoanalytics(framemsg); public void run() { tempintermediateva.start(); while (true) { // todo: create loop process frames each video stream framewithmotiondetection = new framewithmotiondetection(); // interthread message advancedanalytic system.out.println("waiting framemsg"); framewithmotiondetection = framemsg.take(); system.out.println("framemsg received"); }
the pertinent code producer task;
public class advancedvideoanalytics extends thread { framemsg framemsg; framewithmotiondetection framewithmotiondetection; public advancedvideoanalytics (framemsg framemsg) { this.framemsg = framemsg; system.out.println("advancedvideoanalytic framemsg = " + this.framemsg.hashcode()); } // run method includes; // send frame , clusters detected // framemsg framewithmotiondetection = new framewithmotiondetection(); framewithmotiondetection.setmotiondata(contouranalysisresults); framewithmotiondetection.setcurrentframe(frametoexamine); system.out.println("preparing send message awarenessanalytics thread"); framemsg.put(framewithmotiondetection);
the framemsg class;
public class framemsg { // message sent video stream monitors analytic fusion engine private framewithmotiondetection framewithmotiondata; //private string message; // true if consumer should wait // producer send message, // false if producer should wait // consumer retrieve message. private boolean empty = true; public synchronized framewithmotiondetection take() { // wait until message // available. system.out.println("getting ready take framewithmotiondata"); while (empty) { try { wait(10); system.out.println("waiting take framewithmotiondata because empty = true"); } catch (interruptedexception e) {} } // toggle status. empty = true; system.out.println("successfully took framewithmotiondata, empty = " + empty); // notify producer // status has changed. notifyall(); return framewithmotiondata; } public synchronized void put(framewithmotiondetection framewithmotiondata) { // wait until message has // been retrieved. system.out.println("getting ready put framewithmotiondata"); while (!empty) { try { system.out.println("waiting put framewithmotiondata because empty = false"); wait(); } catch (interruptedexception e) {} } // toggle status. empty = false; // store message. this.framewithmotiondata = framewithmotiondata; system.out.println("successfully put framewithmotiondata, empty = " + empty); // notify consumer status // has changed. notifyall(); }
}
interestingly, of framemsg object ids same, , able 'put' framemsg , set empty false producer. however, framemsg object seen consumer returns 'true' empty.
the output extract looks like;
videoanalyticsunittest framemsg = 1704856573 awarenessanalytic framemsg = 1704856573 advancedvideoanalytic framemsg = 1704856573 waiting take framewithmotiondata because empty = true waiting take framewithmotiondata because empty = true (many of these)... preparing send message awarenessanalytics thread getting ready put framewithmotiondata put framewithmotiondata, empty = false waiting take framewithmotiondata because empty = true preparing send message awarenessanalytics thread getting ready put framewithmotiondata waiting put framewithmotiondata because empty = false waiting take framewithmotiondata because empty = true waiting take framewithmotiondata because empty = true waiting take framewithmotiondata because empty = true
and continues last 3 lines until terminate program.
i'm perplexed because; 1. followed example 2. object ids match
yet, consumer never sees non-empty framemsg (which complex object).
have missed obvious?
i using listener send messages, didn't want huge application taking listener space. reading more of comments, seems use listener , pass msg run portion of consumer blocking queue.
if you, pursue communications approach above, or revert listener blocking queue?
as @bhargav modi points out, code running finer issues of writing multi-threaded applications (synchronized-block versus -method, using volatile
declarations on key variables). these issues missed during testing since element of chance required make issues appear (one of notorious ones double checked locking).
this reason use java concurrent classes: there less chance of writing code not thread-safe or has multi-threading issues. in case, synchronousqueue looks replacement. synchronousqueue there no need use empty
variable, this.framewithmotiondata
variable or wait/notifyall mechanics.
Comments
Post a Comment