In most of the threading examples in Java, there is common use of a while(true) block like this:
while(true) {
try {
wait()
} catch (Exception ex) {
/*do something*/
}
}
What is the purpose of using while (true) ? Under what kind of scenarios are they particularly useful?
Client/Server communications?
Thanks,
- Ivar
This kind of construct is used when we create Thread pools and re-usable threads. Basically the while(true) construct prevents the Threads of the pool to ever exit.
An example would be a Producer-Consumer situation where Threads wait() till until the queue is empty and as soon as the queue has data, they are notify()ied and one of the thread consumes the data from the queue and does the processing and then goes back to wait() for additional data to arrive again.
while(true) is useful if you want to do something all the time while your code is running and you don't know how often you have to do it.
Client/Server Communication is one scenario. Other scenarios are animations of games or keeping some values always up to date.
A Thread is seperated from the other code, so your application would not hang by using while(true).
It is usefull to add an exit-flag to your while(true)-loop, so you can stop it if you want to.
Boolean isExit = false; //set this value to true when needed.
while(true) {
try {
if(isExist){
break;
}
wait()
} catch (Exception ex) {
/*do something*/
}
}
This is how you implement a condition variable in Java:
synchronized (this) {
while (true) {
try {
wait();
if (someCondition) {
break;
}
} catch (InterruptedException ex) {
// handle the 'interrupt' case ...
}
}
// Do something that depended on the condition being true.
}
The wait call waits until some other thread does a notify on this, presumably to say that the condition is now true. However, it is possible that the condition has become false before the current thread woke up or that multiple threads were woken up. (Obviously, this depends on the application logic of whatever is calling notify or notifyAll.) So we (re-)check the condition and retry if it isn't true. That is the point of the while (true).
The wait() call must be performed inside a monitor lock on this, and the assumption is that this lock is protecting the state that someCondition is checking.
The other tricky thing is dealing with the InterruptedException that may be thrown by wait(). Some people think it is OK to just squash it. In fact, the correct thing to do is to either to propagate it or to call Thread.interrupt() to set the interrupted flag again, and stop whatever the thread is currently doing. If you don't do this, the thread is effectively going to ignore interrupts ... which is a bad thing.
FWIW - catching Exception rather than InteruptedException is bad practice, and possibly a bug.
The while true causes a infinite loop to stop the thread terminating, for example you don't want your server that is waiting for clients to connect to only check once then to stop checking, you want the server to keep checking over and over. Using a while loop allows you to break; out the loop if something goes wrong.
This is an infinite loop, thus the thread would wait infinitely until an exception (most likely an InterruptedException) occurs.
That example doesn't make much sense by itself, normally you'd do something after the wait() and then wait for the next notify from another thread. You'd then use while(true) to indefinitely wait for the notification, do some stuff, then wait again until the application throws an exception or some condition to break the loop is met.
Related
This IBM developerWorks article states:
“The one time it is acceptable to swallow an interrupt is when you know the thread is about to exit. This scenario only occurs when the class calling the interruptible method is part of a Thread, not a Runnable […]”.
I always implemented Runnable for my threads by now. Giving a Runnable implementation like this:
public class View() implements Runnable {
#Overload
public void run(){
Thread worker = new Thread(new Worker());
worker.start();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
worker.interrupt();
// Thread.currentThread().interrupt();
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement? Doesn’t return; perform a clean enaugh exit already? What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”. What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown? Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
BTW, is it a better code design to extend Thread instead of implementing Runnable?
It resets the interrupt flag. This JavaSpecialists newsletter covers this confusing topic in more detail.
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
So if you know that your code is not going to be used by another component, then you don't need to re-interrupt. However I really wouldn't make that minor optimisation. Who knows how your code is going to be used/reused in the future (even by copy/paste) and consequently I would reset the flag for every interrupt.
Here is an example where return it is not enough:
public void doSomething1() {
while (someCondition1()) {
synchronized {
try {
this.wait();
} catch (InterruptedException e) {
return; // Should be Thread.currentThread().interrupt();
}
}
}
}
public void doSomething2() {
while (someCondition2()) {
doSomething1();
}
}
As the exception throw clears the interrupted state next time doSomething1() is executed the status is cleared and the thread does not terminates.
I prefer extending Thread because it gives you a better understanding of what the thread is doing, but it is not necessarily better code design.
As Brian stated ,it resets the interrupt flag but that doesn't say much. In your case it will do nothing and the View-Thread will keep on running.
When interrupting a Thread, the standard procedure is that the Thread should stop running. It won't do this automatically and you have to implement a way to stop it once it is interrupted.
Using the built-in functionality there are two options:
Have the main loop inside the try-block for the InterruptedException. This way, when it is interrupted you you will be thrown out of the loop and the method will exit.
The above can be bad if you have to save the state as it may corrupt the state. As an alternative, you can set the interrupted-flag (as said when it's thrown. re-interrupt it Interrupt the Thread
Either way, you have to check that the Thread is interrupted in your while-loop (with !Thread.currentThread().isInterrupted()-statement in the while-loop) or it may/will not exit. You're not fulfilling one of the first options and neither checking the flag, so your View-thread will keep on running after being interrupted.
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement?
As a point, I always do. We all copy-and-paste code and swallowing the interrupt is such a serious problem that I as a rule always do it, even if the thread is about to die.
Doesn’t return; perform a clean enough exit already?
If you are sure that it is the last return before the run() method completes and the thread exits, then yes, it not technically necessary. But see above. For posterity, return; doesn't do anything with the interrupt flag.
The question is whether your View class has been wrapped. Are you sure that when you return you are exiting the Thread. Maybe someone is delegating to it. AOP may be in place to do some sort of instrumentation.
What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”.
In general, it is important to not swallow the interrupt when your code is called by some sort of wrapping code (delegation, AOP, etc) which needs the interrupt flag. If you are swallowing it, the wrapper won't be able to use it. But in this case, there is no benefit.
What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown?
Nothing. Once the thread exits the interrupt state is worthless. And actually, it looks like the interrupt state isn't even persisted after the thread is dead.
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("caught");
}
}
});
thread.start();
thread.interrupt();
System.out.println(thread.isInterrupted());
thread.join();
System.out.println(thread.isInterrupted());
Prints:
true
caught
false
Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
I can't. There is no code outside of the thread's run() method unless someone is wrapping your runnable in other code without your knowledge.
This may happen if you are using an ExecutorService but in that case the thread's interrupt status is specifically cleared with a wt.isInterrupted() before the job is run.
So again, the reason is to do is is because it's a good pattern and that's what's important in software engineering.
I am writing a GUI for a program that takes some inputs and runs an algorithm on them. The code for the algorithm is fairly long and complex so I have just been launching a new thread from the GUI in order to perform the computations on the inputs.
//algorithmThread previously initialized
if(e.getSource() == startButton) {
if(update.updateStrings(textFields)) {
algorithmThread.start();
}
}
We want to add functionality that will allow the user to stop the computation (it runs for about half an hour on my laptop before producing a result) in the case that they have provided the wrong input files. This is how I am handling that.
else if(e.getSource() == stopButton) {
//if the user presses the stop button then intterupt the
//thread running the algorithm
algorithmThread.interrupt();
System.out.println("algorithm stopped"); //debugging code
//recreate the thread in case the user hits the start button again
algorithmThread = new Thread() {
public void run() {
runNOC();
}
};
}
The program does successfully stop the algorithm(although I think I should do some exception handling), allow the user to enter new input, and restart. My question is, under what conditions would I have to check Thread.interrupted() in the code for the algorithm? Is it necessary/best practice? Or is it acceptable to stop a thread in the manner illustrated above?
All the Thread.interrupt() method does is set an "interrupted" flag, so stopping a thread in this manner requires its cooperation. For example, the algorithm should poll the interrupt status every once in a while, for example once per iteration. You can see an example of this in the Java concurrency tutorial.
Since you are working with a GUI, you may find it easier to run the background thread using a SwingWorker. This class has many features convenient for GUI programming, like updating the GUI when the computation has finished using the done method and canceling the computation without using Thread.interrupt(). Canceling in this manner still requires cooperation from the thread, but is safer because interrupting a thread causes an InterruptedException to be thrown in some situations, such as when the thread is sleeping in Thread.sleep or waiting on a lock in Object.wait.
interrupt is not always evil following this thread:
Is Thread.interrupt() evil?
Around here, we use this method in one specific place: handling
InterruptedExceptions. That may seem a little strange but here's what
it looks like in code:
try {
// Some code that might throw an InterruptedException.
// Using sleep as an example
Thread.sleep(10000);
}
catch (InterruptedException ie) {
System.err.println("Interrupted in our long run. Stopping.");
Thread.currentThread().interrupt();
}
This does two things for us:
It avoids eating the interrupt exception. IDE auto-exception handlers
always provide you with something like ie.printStackTrace(); and a
jaunty "TODO: Something useful needs to go here!" comment.
It restores
the interrupt status without forcing a checked exception on this
method. If the method signature that you're implementing does not have
a throws InterruptedException clause, this is your other option for
propagating that interrupted status.
This question already has answers here:
What's the difference between Synchronized and Lock in my example?
(2 answers)
What's the difference in using ReentrentLock and Synchronized(object)? [duplicate]
(1 answer)
Closed 5 years ago.
I made a thread pool based on the example on this page.
In the worker thread we have the infinite loop that never lets the thread die and the wait() method call that pauses the thread when there is no work to do:
while (true) {
synchronized(queue) {
loop:while (queue.isEmpty()) { // labled the loop so we can return here
try
{
queue.wait();
if(queue.isEmpty()) // check the condition predicate again
continue loop;
}
catch (InterruptedException ignored)
{
}
}
r = (Runnable) queue.removeFirst();
}
// If we don't catch RuntimeException,
// the pool could leak threads
try {
r.run();
}
catch (RuntimeException e) {
// You might want to log something here
}
The fact is that r = (Runnable) queue.removeFirst(); can throw a NoSuchElementException which is a RuntimeException if the queue is empty. And when such an exception is thrown on that line, the current thread holding the mutex dies and the pool leaks the thread. The mutex seems to be released when the thread dies.
However, if you instead of using the default synchronized keyword to synchronize the queue, use the ReentrantLock to lock and Condition for signaling and awaiting, the current thread that holds the mutex does not seem to release the lock when it interrupts unexpectedly.
So, in my case, when I checked with JVisualVM under the Threads tab I could see that the AWT-EventQueue-0 thread was wating for Thread-1 to release the mutex. But the Thread-1 died upon its way to run the task and was unexpectedly terminated (RuntumeException) and the mutex did not seem to be released.
My questions:
1) Does not ReentrantLocks being released if the thread that holds it terminates unexpectedly?
2) Is there any difference between while (queue.isEmpty()) { and if (queue.isEmpty()) { in the code snippet above? I cannot see any difference since the thread will wait in both cases. But I think the behaviour it different when using if (like if more than one thread can affect the queue).
EDIT
Java Concurrency in Practice states:
For all these reasons, when you wake up from wait you must
test the condition predicate again, and go back to waiting
(or fail) if it is not yet true. Since you can wake
up repeatedly without your condition predicate being true, you
must therefore always call wait from within a loop, testing
thecondition predicate in each iteration.
Look at my edit in the code above, now the code should be correctly as stated in Java Concurrency in Practice.
1) Does not ReentrantLocks being released if the thread that holds it terminates expectedly?
Lock release only when you call Lock#unlock() explicitly. That why recommend to invoke Lock#unlock() in finally block to prevent deadlocks in your application.
2) Is there any difference between while (queue.isEmpty()) { and if
(queue.isEmpty()) { in the code snippet above? I cannot see any
difference since the thread will wait in both cases. But I think the
behaviour it different when using if (like if more than one thread can
affect the queue).
There, no big differences in particular situation. But using while you guarantee assert in your application, you will not invoke removeFirst() when Queue is empty.
Also, PROS for using while instead of if is spurious wakeups.
notes:
If you are implementing this schema not only for education, consider using BlockingQueue. java.util.concurrent library resolved many multithread problems and in most cases you can build application based on the high level abstractions of java.util.concurrent instead of using low-level techniques such as wait()/notify().
Your code seems too complicated - I would simply write:
while (true) {
synchronized(queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException ignored) {
//don't ignore me please
//you probably should exit the loop and return here...
}
}
r = queue.removeFirst(); //Why use a cast? Use generics instead.
}
}
The only situation where queue.removeFirst() could throw a NoSuchElementException is if it is modified concurrently, which is not possible if all accesses to the queue are made in synchronized blocks.
So find the place where you access the queue without holding the lock on the monitor and you will solve your problem.
The reason why you must call wait within a loop is that wait might wake spuriously (i.e. because wait wakes up does not mean your condition has become true so you need to test it again).
As a side note, if you used a BlockingQueue you would not have to worry about those low level details and you could simply write:
while(true) {
Runnable r = queue.take(); //blocks until queue is not empty
}
Stuff in java.util.concurrent give you more flexibility and things like timed waits and try-lock/acquire methods. Also, synchronized gives you code block, unlike lock.lock()/unlock() pairs. It also tends to be more efficient when there is no contention.
Anyway, when using concurrency, one should definitely look into java.util.concurrent since many problems are solved there already.
I've come across the code below, and I'm wondering if it does exactly what I think it does:
synchronized(sObject) {
mShouldExit = true;
sObject.notifyAll()
while (!mExited) {
try {
sObject.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
About the context: there is another thread that checks for mShouldExit (inside the sObject monitor) and will exit in that case.
This does not look to be a correct pattern to me. If an interrupt happens, it will set the interrupted status again, so when it returns to sObject.wait(), another InterruptedException will come etc. etc. etc. Therefore, it can never go to truly waiting state (sObject.wait()) i.e. it will never release the sObject monitor. This may result in an infinite loop, as the other thread cannot set mExiting to true, because it can never enter sObject's monitor. (So I think that the interrupt() call is an error, it must not be used here.) Am I missing something?
Note that the code snippet is a part of the official Android framework source code.
UPDATE: actually, the situation is worse, because the same pattern is used in Android when your GL rendering starts. The official source code of GLSurfaceView.GLThread.surfaceCreated():
public void surfaceCreated() {
synchronized(sGLThreadManager) {
if (LOG_THREADS) {
Log.i("GLThread", "surfaceCreated tid=" + getId());
}
mHasSurface = true;
sGLThreadManager.notifyAll();
while((mWaitingForSurface) && (!mExited)) {
try {
sGLThreadManager.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
You can reproduce the bug in a similar way: make sure your UI thread has its interrupted status flag yet, then add your GLSurfaceView and start the GL rendering (via setRenderer(...), but on some devices, make sure your GLSurfaceView has Visibility.VISIBLE status, otherwise rendering will not start).
If you follow the above steps, your UI thread will end up in an infinite loop, because the above-quoted code will keep generating an InterruptedException (due to wait()) and therefore the GL thread will never be able to set mWaitingForSurface to false.
According to my tests, it seems that such an infinite loop will also result in an endless sequence of GC_CONCURRENT garbage collection (or, at least, such messages in logcat). Interesting, someone had an unknown poorly-defined issue on stackoverflow earlier which might be related:
How to solve GC_concurrent freed?
Isn't it possible that perhaps his UI thread had its interrupted flag set to true, and he was using a GLSurfaceView for the map he mentions? Just an assumption, a possible scenario.
Short version: That code is wrong, and will cause an infinite loop (I still have a doubt, but may depend on JVM implementations). Setting the interrupt status is the right thing to do, but it should then exit the loop, eventually checking that same interruption status using Thread.isInterrupted().
Long version for the casual reader:
The problem is how to stop a thread that is currently executing some work, in response to a "Cancel" button from the user or because of some other application logic.
Initially, Java supported a "stop" method, that preemptively stopped a thread. This method has been demonstrated to be unsafe, cause didn't give the stopped thread any (easy) way to clean up, release resources, avoid exposing partially modified objects and so on.
So, Java evolved to a "cooperative" Thread "interruption" system. This system is quite simple : a Thread is running, someone else calls "interrupt" on it, a flag is set on the Thread, it's Thread responsibility to check if it has been interrupted or not and act accordingly.
So, correct Thread.run (or Runnable.run, of Callable etc..) method implementation should be something like :
public void run() {
while (!Thread.getCurrentThread().isInterrupted()) {
// Do your work here
// Eventually check isInterrupted again before long running computations
}
// clean up and return
}
This is fine as long as all the code your Thread is executing is inside your run method, and you never call something that blocks for a long time ... which is often not the case, cause if you spawn a Thread is because you have something long to do.
The simplest method that block is Thread.sleep(millis), it's actually the only thing it does : it blocks the thread for the given amount of time.
Now, if the interrupt arrives while your thread is inside Thread.sleep(600000000), without any other suport, it would take a lot for it to arrive to the point where it checks isInterrupted.
There are even situations where your thread would never exit. For example, your thread is computing something and sending results to a BlockingQueue with a limited size, you call queue.put(myresult), it will block until the consumer free some space in the queue, if in the mean time the consumer has been interrupted (or died or whatever), that space will never arrive, the method will not return, the check on .isInterrupted will never be performed, your thread is stuck.
To avoid this situation, all (most) methods that interrupt the thread (should) throw InterruptedException. That exception simply tells you "I was waiting for this and that, but in the meanwhile the thread as been interrupted, you should do cleanup and exit as soon as possible".
As with all exceptions, unless you know what to do, you should re-throw it and hope that someone above you in the call stack knows.
InterruptedExceptions are even worse, since when they are thrown the "interrupted status" is cleared. This means that simply catching and ignoring them will result in a thread that usually does not stop :
public void run() {
while (!Thread.getCurrentThread().isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Nothing here
}
}
}
In this example, if the interrupt arrives during the sleep() method (which is 99.9999999999% of the time), it will throw InterruptedException, clear the interrupt flag, then the loop will continue since the interrupt flag is false, and the thread will not stop.
That's why if you implement your "while" correctly, using .isInterrupted, and you really need to catch InterruptedException, and you don't have anything special (like cleanup, return etc..) to do with it, least that you can do is set the interrupt flag again.
The problem in the code you posted is that the "while" relies solely on mExited to decide when to stop, and not ALSO on isInterrupted.
while (!mExited && !Thread.getCurrentThread().isInterrupted()) {
Or it could exit when interrupted :
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return; // supposing there is no cleanup or other stuff to be done
}
Setting the isInterrupted flag back to true is also important if you don't control the Thread. For example, if you are in a runnable which is being executed in a thread pool of some kind, or inside any method anywhere you don't own and control the thread (a simple case : a servlet), you don't know if the interruption is for "you" (in the servlet case, the client closed the connection and the container is trying to stop you to free the thread for other requests) or if it's targeted at the thread (or system) as a whole (the container is shutting down, stopping everything).
In that situation (which is 99% of the code), if you cannot rethrow the InterruptedException (which is, unfortunately, checked), the only way to propagate up the stack to the thread pool that the thread has been interrupted, is setting the flag back to true before returning.
That way, it will propagate up the stack, eventually generating more InterruptedException's, up to the thread owner (be it the jvm itself, of an Executor, or any other thread pool) that can react properly (reuse the thread, let it die, System.exit(1) ...)
Most of this is covered in chapter 7 of Java Concurrency in Practice, a very good book that I recommend to anyone interested in computer programming in general, not just Java, cause the problems and the solutions are similar in many other environments, and explanations are very well written.
Why Sun decided to make InterruptedException checked, when most documentation suggests to rethrow it mercilessly, and why they decided to clear the interrupted flag when throwing that exception, when the proper thing to do is setting it to true again most of the time, remains open for debate.
However, if .wait releases the lock BEFORE checking for the interrupt flag, it open a small door from another thread to modify the mExited boolean. Unfortunately the wait() method is native, so source of that specific JVM should be inspected. This does not change the fact that the code you posted is coded poorly.
In the below code, i have a while(true) loop.
considering a situation where there is some code in the try block where the thread is supposed to perform some tasks which takes about a minute, but due to some expected problem, it is running for ever. can we stop that thread ?
public class thread1 implements Runnable {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 t1 = new thread1();
t1.run();
}
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
try{
Thread.sleep(10);
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
First of all, you are not starting any thread here! You should create a new thread and pass your confusingly named thread1 Runnable to it:
thread1 t1 = new thread1();
final Thread thread = new Thread(t1);
thread.start();
Now, when you really have a thread, there is a built in feature to interrupt running threads, called... interrupt():
thread.interrupt();
However, setting this flag alone does nothing, you have to handle this in your running thread:
while(!Thread.currentThread().isInterrupted()){
try{
Thread.sleep(10);
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
break; //optional, since the while loop conditional should detect the interrupted state
}
catch(Exception e){
e.printStackTrace();
}
Two things to note: while loop will now end when thread isInterrupted(). But if the thread is interrupted during sleep, JVM is so kind it will inform you about by throwing InterruptedException out of sleep(). Catch it and break your loop. That's it!
As for other suggestions:
About Thread.stop():
Deprecated. This method is inherently unsafe[...]
Adding your own flag and keeping an eye on it is fine (just remember to use AtomicBoolean or volatile!), but why bother if JDK already provides you a built-in flag like this? The added benefit is interrupting sleeps, making thread interruption more responsive.
The proper way to stop a thread is to interrupt it (stop() is deprecated and may have nasty side effects):
t1.interrupt()
This will cause an InterruptedException to be thrown by methods like Thread.sleep() or Object.wait().
Then just add a catch block for this exception and simply break out of the while loop.
EDIT: I now realised that your infinite loop is running within the main thread, there's no thread created by your code, it's just run()ning a Runnable. You need to call Thread.start() at some point to spawn a new thread.
Move the catch interrupt to outside the loop. This doesn't require any more lines of code, it just handles interrupts correctly i.e. the action is interrupted.
public void run() {
try{
while(true) {
Thread.sleep(10);
}
} catch(InterruptedException e){
System.out.println("Thread interrupted"));
}
}
The only way to stop an arbitrary thread is by interrupting it. Keep a reference to it then call the interrupt method.
Create a field boolean keepGoing that you set to true before starting your thread and replace while (true) with while (keepGoing). At some point, you decide where, simply change the value of keepGoing to false and it will exit the loop.
I recommend using Thread.interrupt() (as mentioned by #Bohemian). It has a couple of advantages over using ad-hoc flags:
You don't need to create and use an application-specific API to do this. (And interrupts are guaranteed thread-safe ...)
Thread.interrupt() will interrupt threads that are blocked in a wait() or a join, or possibly1 some blocking I/O calls.
However, it is not a magic bullet. If the thread you are trying to stop is executing regular code, it needs to periodically check its interrupted() flag, or it won't no to stop. This leaves us in the same as boat as we are in with an ad-hoc flag mechanism. The thread has to cooperate, or it can't be (safely) stopped.
1 - This is a murky area. On the one hand, there is an InterruptedIOException whose javadoc says "Signals that an I/O operation has been interrupted". On the other hand, the exception is not explicitly mentioned in the javadocs for the various java.io stream classes.
It is true that some 3rd-party code may not deal with the interrupted flag properly, and interrupts may get "eaten" as a result. But you can check for that if you have source code. And the situation is not a lot different to the 3rd-party code not paying attention to your ad-hoc flag mechanism.
I would NOT recommend using Thread.stop(). It is fundamentally flakey. Some people claim that it works for them, but IMO they are either dealing with a special case that works ... or they are being lucky.