Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interrupt BufferedReader's readLine

I am trying to read input from a socket line by line in multiple threads. How can I interrupt readLine() so that I can gracefully stop the thread that it's blocking?

EDIT (bounty): Can this be done without closing the socket?

like image 591
Jack Edmonds Avatar asked Aug 29 '10 18:08

Jack Edmonds


People also ask

How does BufferedReader readLine work?

Class BufferedReader. Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines. The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.

Does readLine read empty lines?

ReadLine does not read last line if it's empty #27715.

Does readLine wait for input?

Bookmark this question. Show activity on this post. After establishing the socket between client and server, the execution halts at reader.


1 Answers

Without closing the socket:

The difficult problem isn't the BufferedReader.readLine, but the underlying read. If a thread is blocked reading, the only way to get it going is to supply some actual data or close the socket (interrupting the thread probably should work, but in practice does not).

So the obvious solution is to have two threads. One that reads the raw data, and will remain blocked. The second, will be the thread calling readLine. Pipe data from the first the second. You then have access to a lock than can be used to wakeup the second thread, and have it take appropriate action.

There are variations. You could have the first thread using NIO, with a single thread instance shared between all consumers.

Alternatively you could write a readLine that works with NIO. This could even take a a relatively simple single-threaded form, as Selector.wakeup exists and works.

like image 108
Tom Hawtin - tackline Avatar answered Sep 21 '22 14:09

Tom Hawtin - tackline