Skip to content

Instantly share code, notes, and snippets.

@amanteaux
Created April 25, 2020 09:14
Show Gist options
  • Save amanteaux/675491e8509f718040f18614bf51c573 to your computer and use it in GitHub Desktop.
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
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
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());
}
}
pi@raspberrypi:~ $ nc -l 1234
Hello from netcat
I am still alive :)
OK see you!
^C
pi@raspberrypi:~ $
@amanteaux
Copy link
Author

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