1

I am using a FileInputStream in a thread in Android java to read from a serial interface file. stream.read(buffer) blocks if there is not data waiting right now, if new data comes in again is continues. Data arrives every now and then, whenever something comes in the thread continues running. That's perfect!

But when I want to terminate the thread it seems I stumble upon a long known bug. thread.interrupt() does not cancel stream.read().
There are lots of questions about that. The only thing that should work is to close the underlying stream. But if I close my FileInputStream stream.read() in my receiver thread still keeps waiting. It only stops after receiving the next bunch of data - that of course then goes a wrong way.

What else can I do to really close or shutdown the FileInputStream?

Edit
After discussing my solution looks like this. It's not best performance and uses available() which is not advised in the docs but it works.

The thread that listens to the file:

byte[] buffer = new byte[1024];
while (!isInterrupted())
{
  if (stream.available() == 0)
  {
    Thread.sleep(200);
    continue;
  }

  // now read only executes if there is something to read, it will not block indefinitely.
  // let's hope available() always returns > 0 if there is something to read.
  int size = stream.read(buffer);

  now do whatever you want with buffer, then repeat the while loop
}

The sleep duration is a tradeoff between not looping all the time and getting data in an acceptable interval. The Mainthread terminates this with

stream.close(); // which has no effect to the thread but is clean
thread.interrupt();
Droidum
  • 440
  • 2
  • 9
  • can you post that block of code? – user1506104 Sep 28 '16 at 08:54
  • Thread is `while (!isInterrupted()) { int size = inputStream.read(buffer); . . . process buffer }` Main thread is: inputStream.close(); – Droidum Sep 28 '16 at 08:59
  • `read` has IOException. are you capturing this? provide more info by showing more of your source code. – user1506104 Sep 28 '16 at 09:02
  • Yes I capture exceptions around the while loop. catch clause is not entered. The line after read (the "process buffer" stuff) gets executed in the old thread when data comes in after close(), so I can clearly say there is no such exception. Well there is not more relevant code :-) Things I do with the buffer are ok, the call to close the stream is just this one line. Breakpoints tell me that the old thread really goes on after read(), then while(!isInterrupted()) is left without an exception. – Droidum Sep 28 '16 at 09:05
  • check my updated answer below. – user1506104 Sep 28 '16 at 09:21

2 Answers2

0

I guess there is nothing you can do with that blocking read operation. Try the available to check if there is available data before reading.

while(!isInterrupted()) {
   int len = 0;
   if(len = inputStream.available() > 0)  
   // read your data
}

Here is another option: How to stop a thread waiting in a blocking read operation in Java?

Community
  • 1
  • 1
user1506104
  • 6,554
  • 4
  • 71
  • 89
  • 1
    Ok thanks for confirming my fear, at least I can stop searching :-) I check for available() in a loop with sleep. available() is documented to be unreliable and busy-waiting is not nice too. But apparently there is no other way. – Droidum Sep 28 '16 at 09:39
  • once you figured out the best solution, please post it here. i am interested to know the solution. ty. – user1506104 Sep 28 '16 at 09:52
  • so did I, see original post – Droidum Sep 28 '16 at 11:11
0

I also meet the same question, But I didn't find the official solution.

So I implemented a method according to my own business scenario.

class ReadThread extends Thread {
   pubulic void run() {
      while(flag) {
        int size = inputStream.read(buffer);
        if(flag) {
           // do something
        }
      }
   }
}

when I want to exit this thread, I will set flag = false. Even this thread is not really exit, suppose the inputStread read someting, I will not handle it.

WillWolf
  • 57
  • 6