From multiple articles around the internet it's advised not to swallow InterruptedException. It makes much more sense to do it with thread pool executors something like this when I'm going to reuse the same thread.
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(() -> {
printNumbers(); // first call
printNumbers(); // second call
});
Thread.sleep(3_000);
executor.shutdownNow(); // will interrupt the task
executor.awaitTermination(3, TimeUnit.SECONDS);
}
private static void printNumbers() {
for (int i = 0; i < 10; i++) {
System.out.print(i);
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // preserve interruption status
break;
}
}
}
Code sample above from DZone.
But in the case of creating new thread each time like:
Object LOCK = new Object();
public void doSomeJob() {
myThread = new Thread(new Runnable() {
public void run() {
try {
synchronized(LOCK) {
System.out.println("Inside run");
LOCK.wait();
}
} catch(InterruptedException ignored){}
}
}
}
Do I still need to call Thread.currentThread().interrupt();? Will that make any sense?
Good references:
https://codepumpkin.com/interrupt-interrupted-isinterrupted-java-multithreading/
http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html
I will give an answer based on section 7.1.2 of great book Concurrency in Practice by Brian Goetz.
In your first example you use ExecutorService. ExecutorService manages it's own threads. You are not the owner of those Threads so you do not know what interruption means to them ( for example ThreadPool might choose to kill Threads that were interrupted and create new ones). That is why you should preserve interruption status when you submit a cancelable task to this pool. This citation applies to this case:
Tasks do not execute in threads they own.They borrow threads owned by a service such as a thread pool. Code that
doesn't own the thread (for a thread pool, any code outside of the thread pool implementation) should be careful to
preserve the interrupted status so that the owning code can eventually act on it, even if the "guest" code acts on the
interruption as well. (If you are housesitting for someone, you don't throw out the mail that comes while they're away - you save it and let them deal with it when they get back, even if you do read their magazines.)
In the second case you manage an instance of Thread manually. So you are the owner of it. Therfore you decide what interruption means to this Thread and you do not have to preserve the Interruption Status in the second case if you do not want to apply any Thread Interruption Policy for it :
What you should not do is swallow the InterruptedException by catching it and doing nothing in the catch block, unless your code is actually implementing the interruption policy for a thread
Note also that Thread Interruption Policy is different than Task Cancellation Policy :
Thread Interruption Policy - defines how Thread reacts to interruption (for example ThreadPool might kill Thread that was interrupted and create a new one). It is defined by the owner of the thread.
Task Cancellation Policy - defines how task reacts to cancellation. Cancellation is usually implemented with interruption. The one who implements the task chooses if task in responsive to interruption. This is easily achieved if your task calls methods that throw InterruptedException. Or you can check the interruption flag of the Thread by calling Thread::isInterrupted (for example in a loop). The implementor of the task chooses how to handle this.
Also you should not take any assumptions of Thread Interruption Policy (if you are not the owner of the Thread). That is why preserving Interruption Status or rethrowing InterruptedException is considered a good practice.
If your lock comes from java.util.concurrent.locks.Lock and is interruptible (using .lockInterruptibly()), it does make sense to interrupt the process so everything might be interrupted and cancelled.
Read chapter Implementation Considerations from the documentation.
But if your lock is non-interruptible (using .lock()) it will not make sense as you won't be able to interrupt the lock.
In your case, you're using wait() which is interruptable as written here, and will throw an InterruptedException.
The explanations in DZone link https://dzone.com/articles/understanding-thread-interruption-in-java in your question are very detailed. Thread.currentThread().interrupt(); raises back interrupted exception status which is cleared before by blocking methods (sleep). It is done to ensure second loop interrupted too (it will catch the exception as it is on the same thread).
Before I finish, I wanted to emphasize on an important detail about
what happens to a thread’s interruption status when a blocking code
responds to interruption by throwing InterruptedException. I had left
out the detail till now to avoid confusion.
Before a blocking code throws an InterruptedException, it marks the
interruption status as false. Thus, when handling of the
InterruptedException is done, you should also preserve the
interruption status by callingThread.currentThread().interrupt().
Let’s see how this information applies to the example below. In the
task that is submitted to the ExecutorService, the printNumbers()
method is called twice. When the task is interrupted by a call
toshutdownNow(), the first call to the method finishes early and then
the execution reaches the second call. The interruption is called by
the main thread only once. The interruption is communicated to the
second execution of the printNumber() method by the call to
Thread.currentThread().interrupt() during the first execution. Hence
the second execution also finishes early just after printing the first
number. Not preserving the interruption status would have caused the
second execution of the method to run fully for 9 seconds.
Where to use Thread.currentThread().interrupt(); depends on your code, second example is not complete to understand the need for it.
Related
I read concurency in practice. Now I want to understand how to handle InterrruptedException
Advices from book:
- Propagate the exception (possibly after some task-specific cleanup),
making your method an interruptible blocking method, too; or
- Restore the interruption status so that code higher up on the call stack can
deal with it.
- Only code that implements a thread's interruption policy
may swallow an interruption request. General-purpose task and library
code should never swallow interruption requests.
First two statements are clear for me but I don't understand third. Can you clarify this? Providing example will preferably.
update(thanks Shubham for the link )
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
or general-purpose library code, as illustrated in Listing 5. It
creates a thread that enumerates prime numbers until it is interrupted
and allows the thread to exit upon interruption. The prime-seeking
loop checks for interruption in two places: once by polling the
isInterrupted() method in the header of the while loop and once when
it calls the blocking BlockingQueue.put() method.
public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
}
I don't understand the bolded text now.
Short answer:
If you can deal with the situation, it is allowed to swallow it.
The interrupted exception occurs when the process occurring in that parallel thread was cancelled, or well, interrupted. So if you are the only one interested in that fact, and you can deal with the situation of having that thread "dead", then you can swallow it.
That is perfectly possible in real life examples. The strategy depends on each situation.
ExecutorService would be an example of the third statement.
This coordinates the execution of multiple runnables(/callables) on the same "actual" thread.
If one runnable is interrupted whilst being executed, that interruption should not affect execution of subsequent runnables.
So, ExecutorService should swallow the interruption, having dealt with it appropriately from the perspective of the interrupted runnable, in order to allow reuse of the thread for the next runnable.
Suppose we write a utility code and there is some clinet code dependent upon our code. If an InterruptedException occurs, it should not be consumed in the utility method (in a try block), it should be thrown and also as InterruptedException clears the interrupt flag, it must be set again to true by invoking interrupt method.
Its the core code which needs to take care of the decision to be taken upon occurrence of an InterruptedException [update] This core code may depend upon the interrupt flag or the InterruptedException to terminate a loop, end thread's execution or any other decision.
Moreover utility or library are the low level code which is invoked from higer level client code. Low level should ideally propogate such exception to let the higher level code manage it.
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
I have a thread which may get stuck and keep running forever. Thus after a certain amount of time, I would like it to stop executing, go to the finally method to do cleanup, and then die. How would I go about doing this safely? Thanks.
My first thought on how to do this was to make a child thread and have that sleep and then do the cleanup. But then when the parent thread is still trying to run and it can't so it outputs an error.
Refactor your code into a Callable and use an ExecutorService to get a Future. Then use get with a timeout, which throws a TimeoutException if not done by then. See https://stackoverflow.com/a/2275596/53897 for a full example.
You need to set timeouts for your blocking calls. If there are no timeouts, abstract the call and time it out that way.
You could create 1 thread the poll the task for its completion status, and kill it if its exceeded some value. The task itself would still require yet another thread. I'd do this by creating tasks which have a staleness value. Poll all tasks periodically, if they are stale, cancel them.
Suggestion 1: If you put your code in a try block with a wait() statement you can catch interruptedException which will then follow to your finally. Another thread will have to send a notify() or notifyAll() to cause the interruption whenever circumstances need to interrupt your thread.
Suggestion 2: I'm only just a beginner with Java but the thread getting stuck means you must be able to throw a custom exception inside your try/finally block.
(1)
Best solution is to send your data with a timeout. Should look something like
try {
mySendingDataLibraryApi.sendData(data, timeout /*, timeUnit */);
// some new APIs enable also to configure the time unit of the required timeout.
// Older APIs typically just use milliseconds.
} catch (TimeoutException e) {
doCleanup(); // your cleanup method.
}
(2)
If this isn't applicable since the API you're using doesn't expose such configuration, second best solution would be to use an interruptible API sendData method and interrupt the executing thread. This relies on the fact that such an interruptible API is provided. I wouldn't count much on the existence of such a method if a timed method isn't provided by the API... Anyway, the code in the thread that executes the task would look like:
class MySendingDataRunnable implements Runnable {
#Override
public void run() {
try {
mySendingDataLibraryApi.sendDataInterruptibly(data);
} catch (InterruptedException e) {
doCleanup(); // your cleanup method.
// here either re-throw InterruptedExecption
// or restore the interrupted state with Thread.currentThread().interrupt();
}
}
}
The code in the caller the thread, should use an ExecutorService and the Future instance returned by its Future<?> submit(Runnable task) method, in order to wait the desired time and cancel the task with the mayInterruptIfRunning argument set to true:
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future<?> future = executor.submit(new MySendingDataRunnable());
try {
final Object noResult = future.get(60, TimeUnit.SECONDS); // no result for Runnable
} catch (InterruptedException e) {
// here again either re-throw or restore interupted state
} catch (ExecutionException e) {
// some applicative exception has occurred and should be handled
} catch (TimeoutException e) {
future.cancel(true); // *** here you actually cancel the task after time is out
}
(3)
If the API you use provide neither of these features (timed / interruptible methods), you'll have to use your creativity! This one line of blocking code of yours must be blocking on some resource. Try to reach out for this resource and shut it down or disconnect from it, implicitly causing the task to terminate. A typical example is closing a network connection.
Note: the above solutions only provide a way of actually cancelling the task and freeing the thread for further tasks. The thread might still be alive though. Killing the thread is usually not something that you do when a task is completed (or failed for that matter). It is acceptable when you've created some thread(s) for specific task(s) which isn't supposed to be executed ever again. In such cases you use the above ExecutorService and invoke its shutdownNow() method. And even shutdownNow() only makes best effort and typically depends on the the actual task to be interruptible...
Here's a detailed article (somewhat old but nonetheless).
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
When does Java's Thread.sleep throw InterruptedException? Is it safe to ignore it? I am not doing any multithreading. I just want to wait for a few seconds before retrying some operation.
You should generally NOT ignore the exception. Take a look at the following paper:
Don't swallow interrupts
Sometimes throwing InterruptedException is
not an option, such as when a task defined by Runnable calls an
interruptible method. In this case, you can't rethrow
InterruptedException, but you also do not want to do nothing. When a
blocking method detects interruption and throws InterruptedException,
it clears the interrupted status. If you catch InterruptedException
but cannot rethrow it, you should preserve evidence that the
interruption occurred so that code higher up on the call stack can
learn of the interruption and respond to it if it wants to. This task
is accomplished by calling interrupt() to "reinterrupt" the current
thread, as shown in Listing 3. At the very least, whenever you catch
InterruptedException and don't rethrow it, reinterrupt the current
thread before returning.
public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
}
}
From Don't swallow interrupts
See the entire paper here:
http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-
If an InterruptedException is thrown it means that something wants to interrupt (usually terminate) that thread. This is triggered by a call to the threads interrupt() method. The wait method detects that and throws an InterruptedException so the catch code can handle the request for termination immediately and does not have to wait till the specified time is up.
If you use it in a single-threaded app (and also in some multi-threaded apps), that exception will never be triggered. Ignoring it by having an empty catch clause I would not recommend. The throwing of the InterruptedException clears the interrupted state of the thread, so if not handled properly that info gets lost. Therefore I would propose to run:
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
// code for stopping current task so thread stops
}
Which sets that state again. After that, finish execution. This would be correct behaviour, even tough never used.
What might be better is to add this:
} catch (InterruptedException e) {
throw new RuntimeException("Unexpected interrupt", e);
}
...statement to the catch block. That basically means that it must never happen. So if the code is re-used in an environment where it might happen it will complain about it.
The Java Specialists newsletter (which I can unreservedly recommend) had an interesting article on this, and how to handle the InterruptedException. It's well worth reading and digesting.
Methods like sleep() and wait() of class Thread might throw an InterruptedException. This will happen if some other thread wanted to interrupt the thread that is waiting or sleeping.
A solid and easy way to handle it in single threaded code would be to catch it and retrow it in a RuntimeException, to avoid the need to declare it for every method.
From the docs:
An InterruptedException is thrown when a thread is waiting,
sleeping, or otherwise occupied, and the thread is interrupted, either
before or during the activity.
In other words, InterruptedException occurs when some code has called the interrupt() method on a specific thread. It's a checked exception, and many blocking operations in Java can throw it.
The purpose of the interrupt system is to provide a alternative workflow for allowing threads to interrupt tasks in other threads. An interruption necessarily may not interrupt a running thread but it can also request that the thread interrupt itself at the next convenient opportunity.
Threads may get blocked for several reasons:
waiting to wake up from a Thread.sleep()
waiting to acquire a lock, waiting for I/O completion
waiting for the result of a computation in another thread, etc.
The InterruptedException is usually thrown by all blocking methods so that it can be handled and the corrective action can be performed.
However, in majority of the cases as our code is a part of a Runnable, in this situation, we must catch it and restore the status.
There are a handfull of methods in Java that throws InterruptedException. Some examples are:
Object class:
Thread.sleep()
Thread.join()
wait()
BlockingQueue:
put()
take()
From personal experience, I simply changed thread.sleep() into this.sleep()
The InterruptedException is usually thrown when a sleep is interrupted.