Pretty sure you've been able to interrupt a thread blocked on IO in a normal InputStream since 1.0.2 in 1996.
There is a significant caveat to this, which is that if the underlying blocking IO operation isn't natively cancellable (and the JDK doesn't use the trick Zig uses here), then the interrupt is allowed to close the IO resource as a way of ending the operation early. In practice this is usually fine, as you're interrupting the thread precisely because you want it to give up on whatever it's doing, but it precludes some particularly subtle possible IO designs.
Not sure if this changes under virtual threads, where the thread is much more loosely coupled to the syscall.
I think that specific issue was a huge mistake, because it means the interruption, which was already messy, is now unusable.
First, you can get deadlocks as interrupt now calls arbitrary code to close channels. Second the interruptee thread cannot recover from an interrupt, if it chooses to to. Lastly it means that a server that shares a file descriptor with multiple threads breaks unrelated operations on interruption.
Who's right though? The article seems to go directly against what parent said above?
In Java, there’s a similarly looking thread interruption mechanism. Critically, it doesn’t support interrupting syscalls: IOException and InterruptedException are both checked and unrelated, meaning that IOing functions are not interruptible
One says IOing functions are not interruptible, other says "You can interrupt a blocking IO operation" :)
The article seems to talk about how `Thread.interrupt` works with synchronous IO, rather than the async IO machinery of `java.nio`. So I'd say the article is inaccurate or at least incomplete.
I know some people hate on it, but I genuinely think that NIO is pretty good just in general.
It actually kind of annoys me; I feel like most Java code I've had to debug/maintain is slow and terrible because most Java engineers lack any ambition so they write the old terrible IO that they learned in university, and for years I guess I kind of erroneously assumed that Java was "bad" at doing IO.
Then I read a book on NIO, started writing my own code with channels and selectors and realized that it actually works quite well, and I found it relatively intuitive and performance was pretty solid.
This is actually a recurring pattern I've found in the Java world; Java has added a lot of great features over the years that make the language more ergonomic and performant and fun to write, but due to its prevalence in the "Enterprise" world and university, it selection biases towards people who refuse to learn anything new, meaning that a lot (the majority?) of Java code feels like it was written in 1997.
I have been writing a lot of Java in my free time, unapologetically using Java 17, 21, and 25 features, and I am actually enjoying it.
Run with the options to dump optimized code to a file. Look at what it’s actually generating for all the byte buffer calls and you’ll see it’s piss-takingly fast. Looking at the Java it shows up as five virtual calls and a bunch of bounds checks. The JIT will turn that into a single x86 instruction in most cases.
Comments
Just here to say that Java as interruptible channels since the beginning of 2000.
You can interrupt a blocking IO operation with either interrupt() or close().
https://docs.oracle.com/en/java/javase/25/docs/api/java.base...
Pretty sure you've been able to interrupt a thread blocked on IO in a normal InputStream since 1.0.2 in 1996.
There is a significant caveat to this, which is that if the underlying blocking IO operation isn't natively cancellable (and the JDK doesn't use the trick Zig uses here), then the interrupt is allowed to close the IO resource as a way of ending the operation early. In practice this is usually fine, as you're interrupting the thread precisely because you want it to give up on whatever it's doing, but it precludes some particularly subtle possible IO designs.
Not sure if this changes under virtual threads, where the thread is much more loosely coupled to the syscall.
I think that specific issue was a huge mistake, because it means the interruption, which was already messy, is now unusable.
First, you can get deadlocks as interrupt now calls arbitrary code to close channels. Second the interruptee thread cannot recover from an interrupt, if it chooses to to. Lastly it means that a server that shares a file descriptor with multiple threads breaks unrelated operations on interruption.
You might want to read the “prior art” section of their article…
Who's right though? The article seems to go directly against what parent said above?
One says IOing functions are not interruptible, other says "You can interrupt a blocking IO operation" :)
The article seems to talk about how `Thread.interrupt` works with synchronous IO, rather than the async IO machinery of `java.nio`. So I'd say the article is inaccurate or at least incomplete.
NIO can be blocking or non-blocking. Indeed you can switch between the two on a single channel.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base...
Sort of.
The article just references Thread.interrupt
I know some people hate on it, but I genuinely think that NIO is pretty good just in general.
It actually kind of annoys me; I feel like most Java code I've had to debug/maintain is slow and terrible because most Java engineers lack any ambition so they write the old terrible IO that they learned in university, and for years I guess I kind of erroneously assumed that Java was "bad" at doing IO.
Then I read a book on NIO, started writing my own code with channels and selectors and realized that it actually works quite well, and I found it relatively intuitive and performance was pretty solid.
This is actually a recurring pattern I've found in the Java world; Java has added a lot of great features over the years that make the language more ergonomic and performant and fun to write, but due to its prevalence in the "Enterprise" world and university, it selection biases towards people who refuse to learn anything new, meaning that a lot (the majority?) of Java code feels like it was written in 1997.
I have been writing a lot of Java in my free time, unapologetically using Java 17, 21, and 25 features, and I am actually enjoying it.
Run with the options to dump optimized code to a file. Look at what it’s actually generating for all the byte buffer calls and you’ll see it’s piss-takingly fast. Looking at the Java it shows up as five virtual calls and a bunch of bounds checks. The JIT will turn that into a single x86 instruction in most cases.
Name checks out.