Created
April 25, 2020 09:14
-
-
Save amanteaux/675491e8509f718040f18614bf51c573 to your computer and use it in GitHub Desktop.
Java IO operations cannot be stopped unless they are specifically written to do so
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Thread will maybe be stopped in 5 seconds... 1587805793341 | |
Message from remote at 1587805796619: Hello from netcat | |
Is thread dead yet? 1587805798342 | |
Message from remote at 1587805811746: I am still alive :) | |
Message from remote at 1587805818037: OK see you! | |
End of thread process: 1587805818939 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.net.InetAddress; | |
import java.net.Socket; | |
public class JavaIoOperationThreadInterrupt { | |
public static void main(String[] args) throws IOException, InterruptedException { | |
Thread thread = new Thread(() -> { | |
try { | |
Socket s = new Socket(InetAddress.getByName("192.168.1.27"), 1234); | |
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); | |
String t; | |
while((t = br.readLine()) != null) { | |
System.out.println("Message from remote at "+System.currentTimeMillis()+": " + t); | |
} | |
br.close(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} finally { | |
System.out.println("End of thread process: " + System.currentTimeMillis()); | |
} | |
}); | |
thread.start(); | |
System.out.println("Thread will maybe be stopped in 5 seconds... " + System.currentTimeMillis()); | |
Thread.sleep(5000L); | |
thread.interrupt(); | |
System.out.println("Is thread dead yet? " + System.currentTimeMillis()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pi@raspberrypi:~ $ nc -l 1234 | |
Hello from netcat | |
I am still alive :) | |
OK see you! | |
^C | |
pi@raspberrypi:~ $ |
Hi @danielcuadra, thank you for your response!
Though your solution seems to be perfectly working, in general if you need interruptible IO, the easiest solution is to switch to Java NIO implementations.
Here is a quick and dirty adaptation of the initial non-interruptible IO example to make it interruptible using java.nio.channels.SocketChannel
:
Thread thread = new Thread(() -> {
try {
SocketChannel s = SocketChannel.open();
s.connect(new InetSocketAddress("192.168.1.27", 1234));
BufferedReader br = new BufferedReader(new InputStreamReader(s.socket().getInputStream()));
String t;
while((t = br.readLine()) != null) {
System.out.println("Message from remote at "+System.currentTimeMillis()+": " + t);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("End of thread process: " + System.currentTimeMillis());
}
});
With this implementation, I have now this output:
Thread will maybe be stopped in 5 seconds... 1588930581482
Message from remote at 1588930584618: Hello from netcat
Is thread dead yet? 1588930586484
java.nio.channels.ClosedByInterruptException
at java.base/java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:199)
at java.base/sun.nio.ch.SocketChannelImpl.endRead(SocketChannelImpl.java:334)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:361)
at java.base/sun.nio.ch.SocketAdaptor$SocketInputStream.read(SocketAdaptor.java:203)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185)
at java.base/java.io.BufferedReader.fill(BufferedReader.java:161)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:326)
at java.base/java.io.BufferedReader.readLine(BufferedReader.java:392)
at test.JavaIoOperationThreadInterrupt.lambda$0(JavaIoOperationThreadInterrupt.java:18)
at java.base/java.lang.Thread.run(Thread.java:834)
End of thread process: 1588930586489
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You are right @amanteaux! Java socket does not hear for interruption.
However, this one issue could be worked-around like this (not always a choice):