multithreading - Java: Two threads communicating via streams is company, three's a crowd -


in code segment, create pipe , attach scanner on 1 end , printstream on other in order communicate between several consumer , producer threads. create , start 3 threads:

  1. the first thread consumer thread. checks scanner see if line of text available consume, consumes it, prints stdout , sleeps few milliseconds , repeats. if there's nothing consume, prints message that, sleeps , repeats.

  2. the second thread in code segment nothing. more on below.

2.5 there's 3 second delay before 3rd thread launches.

  1. the third thread producer , produces text messages first thread consume. produces message, sleeps

public static void main(string[] args) throws ioexception {     pipedinputstream pis = new pipedinputstream();     pipedoutputstream pos = new pipedoutputstream(pis);     scanner scan = new scanner(pis);     printstream ps = new printstream(pos);      new thread()     {         public void run()         {             int x = 0;             while (true)             {                 x++;                 if (scan.hasnextline())                 {                     system.out.println("pulled: " + scan.nextline());                 } else                 {                     if (x % 100 == 0)                     {                         system.out.println("no data pull");                     }                 }                 try                 {                     sleep(10);                 } catch (interruptedexception ex) { }             }         }     }.start();      new thread()     {         public void run()         {         }     }.start();      try     {         sleep(3000);     } catch (interruptedexception ex) { }      new thread()     {         public void run()         {             int x = 0;             while (true)             {                 x++;                 ps.println("hello: " + x);                 try                 {                     sleep(1000);                 } catch (interruptedexception ex) {}             }         }     }.start(); } 

the output (as expect):

pulled: hello: 1 pulled: hello: 2 pulled: hello: 3 pulled: hello: 4 pulled: hello: 5 pulled: hello: 6 

also note scan.nextline() blocking (since there no messages indicating no data available... data "available" if it's "on way").

now, if replace body of 2nd thread code produces text first thread consume:

new thread() {     public void run()     {         ps.println( "interfere");     } }.start(); 

then start trigger no data clause of first thread:

pulled: interfere no data pull no data pull no data pull no data pull no data pull no data pull no data pull no data pull 

so if second thread starts using printstream object produce messages, goes wrong in pipe , consumer thread stops being able find messages on other end.

and things weirder. if prevent second thread finishing, throwing long loop, pipe doesn't gummed up:

new thread() {     public void run()     {         ps.println("interfere");         ( long = 0; < 10000000000l; i++ );         system.out.println("done interfering" );     } }.start(); 

output:

pulled: interfere pulled: hello: 1 pulled: hello: 2 done interfering pulled: hello: 3 pulled: hello: 4 pulled: hello: 5 pulled: hello: 6 

so think if second thread terminates before third thread starts producing, first thread won't ever messages third thread. however, if the second thread manages hang on until third thread starts producing goes through expected.

what's going on here? second thread closing pipe/stream (or performing other action on pipe/stream) when terminates? if so, why? , why not seem close (or perform whatever action on) pipe/stream if third thread starts using pipe/stream before second thread terminates? there way make code "work" expected (that first thread consumes whatever produced either/both producer threads) when second thread produces messages , terminates before third thread starts?

background: condensing essential components of system in several clients consume messages single producer thread. however, producer thread can't started until client threads have signaled ready. each client thread, there's thread queries if ready. once client threads have signaled ready, producer thread launched. i'm trying have threads communicate via streams later can distribute them on several computers , set pipes using sockets minimal amount of change underlying code. feel free suggest alternate solution strategy here well, i'd understand why solution above doesn't work.

your scanner instance hitting exception in readinput method sets sourceclosed field true , prevents reading. if you're interested in happens:

private void readinput() {     ...      int n = 0;     try {         n = source.read(buf);     } catch (ioexception ioe) {         lastexception = ioe;         n = -1;     }      if (n == -1) {         sourceclosed = true;         needinput = false;     }      ... } 

this behavior isn't wrong, need fix underlying exception. issue here java.io.ioexception: write end dead. there bunch of answers , blog posts can address better can. take @ related "read end dead" issue. check out:


Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo