Java thread interrupts and joins (thread is still alive after join) - java

I'm trying to figure out some behavior. I've got some code that spawns one thread. It waits some amount of time, and then interrupts it, joins it and then exits the method.
.
.
.
try {
Thread.sleep(processForMillis);
}
catch (InterruptedException ex) {
// Won't happen, ignore.
}
for (Thread t : threads) {
logger.debug("Interrupting Thread " + t.getName());
t.interrupt();
}
for (Thread t : threads) {
try {
t.join(1000L);
logger.debug("Joined Thread " + t.getName());
logger.debug("isAlive? " + t.isAlive());
}
catch (InterruptedException ex) {
// this will never happen
logger.debug("InterruptionException while joining, but didn't expect it.");
}
}
} // end of method
I am currently running this with just one thread. I can see in my logs that usually, isAlive() will be false after the join, but sometimes it is still alive. The thread is sitting in a while loop:
while(!Thread.currentThread().isInterrupted()){
.
// do some blocking io stuff here
}
So what I suspect is happening is we are interrupting the thread while it is reading/processing the inputstream (blocking io) and it is taking more than the time it takes to hit the while conditional and finish the join.
So my question is, what happens to the thread?
It is no longer referenced and the thread can be garbage collected, but none of of the resources are cleaned up properly, and that seems bad. Is there a better pattern for this besides switching to NIO?

interrupt() just sets a flag on the thread that it has been interrupted. Many blocking calls does not unblock when this occurs, meaning the thread is pretty much unaffected by the interrupt and keeps doing its thing(e.g. blocking on an InputStream).
I'm guessing in some cases the thread doesn't unblock and hit your while condition in the given join timeout (1 second here), in other cases the blocking call happens to complete within the timeout and the thread ends.
As long as a thread is running it will still have a reference and not be garbage collected.
If the blocking call never unblocks - which could happen if it reads from e.g. a dead tcp sockets whos other end has silently disappeard, the thread might never end.

In addition to the nos's answer, to interrupt a blocking IO call you can close() its stream

Related

Why jdk Thread.stop()/suspend()/resume() functions are not safe and obsoleted? [duplicate]

Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged

How do i stop a Thread in java, I see a line over the stop? [duplicate]

Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged

Does an InterruptException cause the thread to stop

I thought that the currently executing Thread will be stooped if the exception is thrown. Bu when I was going throught a java test a came across with the question:
Under which conditions will a currently executing thread stop?
When an interrupted exception occurs.
When a thread of higher priority is ready (becomes runnable).
When the thread creates a new thread.
When the stop() method is called.
A. 1 and 3
B. 2 and 4
C. 1 and 4
D. 2 and 3
The right answer was B, but what then happens if the exception is thrown? I thought the thread is terminating.
The right answer was B
No it wasn't. None of the answers given is correct.
but what then happens if the exception is thrown? I thought the thread is terminating.
No. The thread catches InterruptedException from whatever method it was calling that can throw it, for example Thread.sleep(). If it doesn't call such a method, nothing happens at all.
When a method throws InterruptedException, it is telling that it is a blocking method and that it will make an attempt to unblock and return early -- if you ask nicely.
When you try to interrupt a thread by calling interrupt() on the thread instance, it merely sends a signal. It depends on the actual thread to respond to that signal. Methods like Thread.sleep() and Object.wait() can look for this signal and make an attempt to stop what it is doing and return early and indicate its early return by throwing InterruptedException. So it's usually an acknowledgement from some blocking methods to the interrupt() request sent by some other thread.
Thread t = new Thread(() -> {
try {
Thread.sleep(5000); // Thread.sleep() allows a cancellation mechanism
} catch (Exception e) {
System.out.println("interrupted by some one else from outside");
}
});
t.start();
try {
t.interrupt();
t.join(); // waiting for the thread to finish its execution
System.out.println("back in main");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
Output :
interrupted by some one else from outside
back in main
But if you have thread like this
Thread t = new Thread(() -> {
try {
for(int i=0;i<1_000_000;i++){
System.out.println(i);
}
} catch (Exception e) {
System.out.println("interrupted by some one else from outside");
}
});
Calling interrupt() on above thread will not do anything useful because we're not looking for the signal, so thread will print all numbers and join the main thread as if nobody ever asked it to stop doing what it is doing.
In case you want to learn more about this InterruptedException, I highly recommend thisBrian Goetz's article from IBM Developer Works
A thread, t, will stop if some other thread calls t.stop(), but please don't ever do that! One thread should never force another thread to do anything. Threads should always cooperate. Any program that calls t.stop() is very likely to contain bugs that you won't be able to fix without getting rid of the stop() call.
A thread will terminate (which is a kind of stop, right?) if some external process kills the JVM.
A daemon thread will terminate if the JVM shuts down because there are no non-daemon threads left to keep it alive.
A thread may stop or terminate because of the action of an attached debugger.
The only other reason why a thread will stop (and terminate) is if its run() method completes. A method can either complete normally by returning, or it can terminate abnormally (i.e., an exception is thrown and not caught within the method call.) A thread will terminate if its run() method completes in either way.
An InterruptedException doesn't affect a thread any differently from any other exception. If the thread catches the exception, then the thread will continue to run, but if no method in the thread catches it, then the thread's run() method will abnormally complete, and the thread will terminate (stop).

Thread.stop() - deprecated

Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged

Is Thread.interrupt really stops program execution?

I am stopping the thread execution using Thread.interrupt but the thread execution won't stopped . It's still running .
Example :
Thread t = new Thread(new Runnable() {
#Override
public void run() {
int i = 0;
while(i<10000){
if(Thread.currentThread().isInterrupted()){
System.out.println("Thread Interrupted but it still running");
}
System.out.println(++i);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
t.interrupt();
I can't check Thread.isInterrupted() then if thread is interrupted break out of the loop . I can't do this . Here , I am just showing the sample example .
My doubt is Thread.interrupt is only sets interrupted flag only or it really stops the execution .
any help regarding this will be appreciated.
How can I stop the thread execution or kill the running thread?
Thread.interrupt() will genuinely interrupt an operation that actually checks for that state (either, say, an interruptible I/O operation or else some user code that explicitly checks isInterrupted() as in principle you do in the code you quote).
In the specific example you quote, you need to bear in mind that:
each processor core executes in the order of billions of instructions
per second;
process switching occurs in the order of tens to hundreds
of times per second.
In other words, your task of decrementing a counter 10,000 times is something that happens so fast that to all intents and purposes it will barely register as being an "interruptible task". In practice, either all 10,000 decrements will happen before the other thread has chance to call interrupt() or they won't.
If the thread is blocked on wait, sleep or join then InterruptedException is thrown otherwise interrupted status is set.
Interrupted status is cleared if Thread.interrupted is called.
Thread.isInterrupted does not clear the interrupted status.
If the thread's interrupted status is set and this thread calls wait, sleep or join then interrupted status is cleared and InterruptedExcepion is thrown.
It only sets the flag UNLESS an interruptable statement (e.g. sleep, wait) was executing at the time. Now you should be able to work out how to stop the thread, by dealing with both situations.
I can't check Thread.isInterrupted() then if thread is interrupted
break out of the loop . I can't do this .
Why not?
E.g.
while(i<10000){
if(Thread.currentThread().isInterrupted()){
System.out.println("Thread Interrupted but it still running");
return; // HERE
}
System.out.println(++i);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
return; // HERE
}
}
My doubt is Thread.interrupt is only sets interrupted flag only or it really stops the execution.
It does the former ... or throws an "interrupted" exception in certain circumstances.
How can I stop the thread execution or kill the running thread?
In general, you cannot safely stop or kill a running thread that is not checking its interrupted flag. There are some deprecated methods on the Thread class, but you should avoid using them as they are manifestly unsafe. (To understand why the Thread method javadocs ... and the FAQ that it links to.)

Categories