http://blog.longjiazuo.com/archives/5127
https://www.yegor256.com/2017/01/17/synchronized-decorators.html
I think the right approach is to have two classes. The first one is not thread-safe, while the other one is a synchronized decorator,
class SyncPosition implements Position {
private final Position origin;
SyncPosition(int number) {
this.origin = new Position(i);
}
@Override
public synchronized void increment() {
this.origin.increment();
}
}
https://www.yegor256.com/2018/03/27/how-to-test-thread-safety.html
https://www.yegor256.com/2014/06/20/limit-method-execution-time.html
In some circumstances, this may make the interrupt() method less useful in stopping a thread than directly setting a boolean flag in the target thread. However, because it will interrupt the sleep() and wait() methods, and because of some thread management technique
https://www.ibm.com/developerworks/library/j-jtp05236/
There is a flag in every thread that we can set from the outside. And the thread may check it occasionally and stop its execution
When I call
The code should either be bullet-fast or interruption-ready, nothing in between.
https://daniel.mitterdorfer.name/articles/2015/handling-interruptedexception/
As its name indicates, some method has been interrupted during execution. In Java, cancellation of a running thread is cooperative. That means that we cannot force a thread to terminate from the outside 1 but instead we can just request that it interrupts itself and rely that the code executed within a thread will notice the request and act accordingly. To achieve that, each thread manages a flag, the interruption status. It can be set with
https://stackoverflow.com/questions/2523721/why-do-interruptedexceptions-clear-a-threads-interrupted-status
http://www.javaspecialists.eu/archive/Issue056.html
that was the same as having all your code unprotected, and receiving an asynchronous exception in your Thread. The exception that is thrown asynchronously is
Using
We cannot shut down a thread waiting to enter a synchronized block, so if you have a livelock or deadlock you will not be able to shut down your system cleanly.
But, what about when you're blocked on IO? There is an exception called
Don't swallow InterruptedException. Call Thread.currentThread().interrupt() instead.
http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html
There is no way to simply stop a running thread in java (don't even consider using the deprecated method stop()). Stopping threads is cooperative in java. Calling Thread.interrupt() is a way to tell the thread to stop what it is doing. If the thread is in a blocking call, the blocking call will throw an InterruptedException, otherwise the interrupted flag of the tread will be set. A Thread or a Runnable that is interruptable should check from time to time Thread.currentThread().isInterrupted(). If it returns true, cleanup and return.
The problem is that blocking calls like sleep() and wait(), can take very long till the check can be done. Therefore they throw an InterruptedException. However the isInterrupted is cleared when the InterruptedException is thrown! (I have some vague idea why this is the case, but for whatever reason this is done, that is how it is!)
Why can't InterruptedException be simply ignored?
It should be clear by now: because ignoring an InterruptedException means resetting the interrupted status of the thread. For example, worker threads take runnable from a queue and execute they may check the interrupted status periodically. If you swallow it the thread would not know that it was interrupted and would happily continue to run.
https://www.ibm.com/developerworks/library/j-jtp05236/index.html
https://www.yegor256.com/2017/01/17/synchronized-decorators.html
I think the right approach is to have two classes. The first one is not thread-safe, while the other one is a synchronized decorator,
class SyncPosition implements Position {
private final Position origin;
SyncPosition(int number) {
this.origin = new Position(i);
}
@Override
public synchronized void increment() {
this.origin.increment();
}
}
https://www.yegor256.com/2018/03/27/how-to-test-thread-safety.html
CountDownLatch latch = new CountDownLatch(1);
AtomicBoolean running = new AtomicBoolean();
AtomicInteger overlaps = new AtomicInteger();
Collection<Future<Integer>> futures =
new ArrayList<>(threads);
for (int t = 0; t < threads; ++t) {
final String title = String.format("Book #%d", t);
futures.add(
service.submit(
() -> {
latch.await();
if (running.get()) {
overlaps.incrementAndGet();
}
running.set(true);
int id = books.add(title);
running.set(false);
return id;
}
)
);
}
latch.countDown();
Set<Integer> ids = new HashSet<>();
for (Future<Integer> f : futures) {
ids.add(f.get());
}
https://www.yegor256.com/2014/06/20/limit-method-execution-time.html
Most I/O operations in JDK are designed this way. They check the interruption status of their threads while waiting for I/O resources.
Due to
@Timeable
annotation and class weaving, every call to a method load()
is intercepted by an aspect from jcabi-aspects. That aspect starts a new thread that monitors the execution of a method every second, checking whether it is still running.
If the method runs for over five seconds, the thread calls
interrupt()
on the method's thread.In some circumstances, this may make the interrupt() method less useful in stopping a thread than directly setting a boolean flag in the target thread. However, because it will interrupt the sleep() and wait() methods, and because of some thread management technique
https://www.ibm.com/developerworks/library/j-jtp05236/
When a method throws
InterruptedException
, it is telling you several things in addition to the fact that it can throw a particular checked exception. It is telling you that it is a blocking method and that it will make an attempt to unblock and return early -- if you ask nicely.
Because blocking methods can potentially take forever if the event they are waiting for never occurs, it is often useful for blocking operations to be cancelable. (It is often useful for long-running non-blocking methods to be cancelable as well.) A cancelable operation is one that can be externally moved to completion in advance of when it would ordinarily complete on its own. The interruption mechanism provided by
Thread
and supported by Thread.sleep()
and Object.wait()
is a cancellation mechanism; it allows one thread to request that another thread stop what it is doing early. When a method throws InterruptedException
, it is telling you that if the thread executing the method is interrupted, it will make an attempt to stop what it is doing and return early and indicate its early return by throwing InterruptedException
. Well-behaved blocking library methods should be responsive to interruption and throw InterruptedException
so they can be used within cancelable activities without compromising responsiveness.
when a thread is interrupted by some other thread through a call to
Thread.interrupt()
, one of two things happens. If that thread is executing a low-level interruptible blocking method like Thread.sleep()
, Thread.join()
, orObject.wait()
, it unblocks and throws InterruptedException
. Otherwise, interrupt()
merely sets the thread's interruption status. Code running in the interrupted thread can later poll the interrupted status to see if it has been requested to stop what it is doing
If throwing
InterruptedException
means that a method is a blocking method, then calling a blocking method means that your method is a blocking method too, and you should have a strategy for dealing with InterruptedException
. Often the easiest strategy is to throw InterruptedException
yourself, as shown in the putTask()
and getTask()
methods in Listing 1. Doing so makes your method responsive to interruption as well and often requires nothing more than adding InterruptedException
to your throws clause.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 callinginterrupt()
to "reinterrupt" the current thread
If you cannot rethrow
https://www.yegor256.com/2015/10/20/interrupted-exception.htmlInterruptedException
, whether or not you plan to act on the interrupt request, you still want to reinterrupt the current thread because a single interruption request may have multiple "recipients." The standard thread pool (ThreadPoolExecutor
) worker thread implementation is responsive to interruption, so interrupting a task running in a thread pool may have the effect of both canceling the task and notifying the execution thread that the thread pool is shutting down. If the task were to swallow the interrupt request, the worker thread might not learn that an interrupt was requested, which could delay the application or service shutdown.There is a flag in every thread that we can set from the outside. And the thread may check it occasionally and stop its execution
When I call
loop.interrupt()
, a flag is set to true
somewhere inside the thread loop
. When I call interrupted()
, the flag is returned and immediately set to false
. Yeah, that's the design of the method. It checks the flag, returns it, and sets it to false
The code should either be bullet-fast or interruption-ready, nothing in between.
The owner of the thread asked us to stop,
Thread.sleep()
detected that request, removed it, and threw InterruptedException
. If you call Thread.sleep()
, again, it will not know anything about that interruption request and will not throw anything.
See what I'm getting at? It's very important not to lose that
InterruptedException
. We can't just swallow it and move on. That would be a severe violation of the entire Java multi-threading idea.
It looks logical, but it doesn't guarantee that the higher level will actually stop everything and exit. They may just catch a runtime exception there, and the thread will remain alive. The owner of the thread will be disappointed.
We have to inform the higher level that we just caught an interruption request.
catch (InterruptedException ex) {
Thread.currentThread().interrupt(); // Here!
throw new RuntimeException(ex);
}
As its name indicates, some method has been interrupted during execution. In Java, cancellation of a running thread is cooperative. That means that we cannot force a thread to terminate from the outside 1 but instead we can just request that it interrupts itself and rely that the code executed within a thread will notice the request and act accordingly. To achieve that, each thread manages a flag, the interruption status. It can be set with
Thread#interrupt()
and reset with Thread#interrupted()
. Additionally, Thread#isInterrupted()
is used to check the interruption status.class Simulation implements Runnable {
@Override
public void run() {
while (!Thread.currentThread.isInterrupted()) {
// ... simulation calculations here ...
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// restore interruption status of the corresponding thread
Thread.currentThread.interrupt();
}
}
}
}
The idea is that an interrupt should be handled once. If an explicit
InterruptedException
did not clear the "interrupt" flag then most catchers for InterruptedException
would have to explicitly clear that flag. Conversely, you can "unclear" the flag by self-interruption (Thread.currentThread().interrupt()
). Java's designers went for the semantics which would save keystrokes most of the time (i.e. you more often want to clear the flag than keep it set).
That's because an
InterruptedException
is considered an abnormal event in which someone else tries to stop a thread from outside it.
When you want to really interrupt a thread you just break its loop condition by setting a boolean or something similar. Or you use
.wait()
and .notify()
from inside that thread. But if you are doing wait()
externally:- an exception is thrown to notify that an external thread tried to interrupt me or to make me wait
- the thread continues its work because it doesn't take any order from another thread! But the raise of the exception allows you to add special handling and do whatever you want, also effectively stop the thread.
that was the same as having all your code unprotected, and receiving an asynchronous exception in your Thread. The exception that is thrown asynchronously is
java.lang.ThreadDeath
Using
stop()
is incredibly dangerous, as it will kill your thread even if it is in the middle of something important. There is no way to protect yourself, so if you spot code that uses stop()
, you should frown.
the only place where we are allowed to receive an exception to tell us that the thread is being shutdown is while the thread is blocked. Getting a shutdown notification at any other time would be dangerous and nondeterministic. The way this works is via the
java.lang.InterruptedException
. I admit that InterruptedException
is not the most obvious choice of name for indicating that another thread is trying to shutdown your thread.
I have seen code that uses a boolean flag to indicate whether the thread is running or not. However, Java already provides that flag in the form of the interrupted flag, so why duplicate effort?
public class UsingFlagToShutdownThread extends Thread { private volatile boolean running = true; public void run() { while (running) { System.out.print("."); System.out.flush(); try { Thread.sleep(1000); } catch (InterruptedException ex) {} } System.out.println("Shutting down thread"); } public void shutdown() { running = false; } public static void main(String[] args) throws InterruptedException { UsingFlagToShutdownThread t = new UsingFlagToShutdownThread(); t.start(); Thread.sleep(5000); t.shutdown(); } }
What is so bad with that code? This example is not too bad, since the longest we would wait unnecessarily would be one second. However if we normally sleep for 30 seconds, then it could take a while before your program is completely shut down. This is especially true if you have a lot of threads and you
join()
each one to make sure that it does finish.
Java has another mechanism that you should rather use: simply interrupt the thread. The code would then look like this:
public class UsingInterruptToShutdownThread extends Thread { public void run() { while (true) { System.out.print("."); System.out.flush(); try { Thread.sleep(1000); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); // very important break; } } System.out.println("Shutting down thread"); }
Why do we have to interrupt the thread again?
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. Consider the following code:public class NestedLoops extends Thread {
private static boolean correct = true;
public void run() {
while (true) {
System.out.print(".");
System.out.flush();
for (int i = 0; i < 10; i++) {
System.out.print("#");
System.out.flush();
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
if (correct) Thread.currentThread().interrupt();
System.out.println();
System.out.println("Shut down inner loop");
break;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
if (correct) Thread.currentThread().interrupt();
System.out.println();
System.out.println("Shut down outer loop");
break;
}
}
System.out.println("Shutting down thread");
}
private static void test() throws InterruptedException {
Thread t = new NestedLoops();
t.start();
Thread.sleep(6500);
t.interrupt();
t.join();
System.out.println("Shutdown the thread correctly");
}
public static void main(String[] args)
throws InterruptedException {
test();
correct = false;
test();
}
}
When you run this code, you will see something like this:
.##########.##########.##########.######
Shut down inner loop
Shut down outer loop
Shutting down thread
Shutdown the thread correctly
.##########.##########.##########.######
Shut down inner loop
.##########.##########.##########.##########.##########. etc.
Herein lies the danger with this approach: if some library incorrectly handles
InterruptedException
then your code will not shut down correctly.
From a purely theoretical view, you should use the interrupt mechanism of threads to shut them down. However, you have to be very careful that you use that mechanism throughout your code, otherwise you will not be able to shut down all your threads.
We cannot shut down a thread waiting to enter a synchronized block, so if you have a livelock or deadlock you will not be able to shut down your system cleanly.
But, what about when you're blocked on IO? There is an exception called
java.io.InterruptedIOException
, which is supposed to cover the situation where you interrupt a thread that is waiting on some IO to complete. As you might have guessed, it is not implemented consistently. It works for piped streams, but none of the others seem to have that effect.Don't swallow InterruptedException. Call Thread.currentThread().interrupt() instead.
http://michaelscharf.blogspot.com/2006/09/dont-swallow-interruptedexception-call.html
try { doSomething(); } catch(InterruptedException e) { // Restore the interrupted status Thread.currentThread().interrupt(); }
There is no way to simply stop a running thread in java (don't even consider using the deprecated method stop()). Stopping threads is cooperative in java. Calling Thread.interrupt() is a way to tell the thread to stop what it is doing. If the thread is in a blocking call, the blocking call will throw an InterruptedException, otherwise the interrupted flag of the tread will be set. A Thread or a Runnable that is interruptable should check from time to time Thread.currentThread().isInterrupted(). If it returns true, cleanup and return.
The problem is that blocking calls like sleep() and wait(), can take very long till the check can be done. Therefore they throw an InterruptedException. However the isInterrupted is cleared when the InterruptedException is thrown! (I have some vague idea why this is the case, but for whatever reason this is done, that is how it is!)
Why can't InterruptedException be simply ignored?
It should be clear by now: because ignoring an InterruptedException means resetting the interrupted status of the thread. For example, worker threads take runnable from a queue and execute they may check the interrupted status periodically. If you swallow it the thread would not know that it was interrupted and would happily continue to run.
https://www.ibm.com/developerworks/library/j-jtp05236/index.html
The most common response to
InterruptedException
is to swallow it -- catch it and do nothing (or perhaps log it, which isn't any better) Unfortunately, this approach throws away important information about the fact that an interrupt occurred, which could compromise the application's ability to cancel activities or shut down in a timely manner.Thread interruption
Every thread has a Boolean property associated with it that represents its interrupted status. The interrupted status is initially false; when a thread is interrupted by some other thread through a call to
Thread.interrupt()
, one of two things happens. If that thread is executing a low-level interruptible blocking method like Thread.sleep()
, Thread.join()
, orObject.wait()
, it unblocks and throws InterruptedException
. Otherwise, interrupt()
merely sets the thread's interruption status. Code running in the interrupted thread can later poll the interrupted status to see if it has been requested to stop what it is doing; the interrupted status can be read with Thread.isInterrupted()
and can be read and cleared in a single operation with the poorly named Thread.interrupted()
.
Interruption is a cooperative mechanism. When one thread interrupts another, the interrupted thread does not necessarily stop what it is doing immediately. Instead, interruption is a way of politely asking another thread to stop what it is doing if it wants to, at its convenience. Some methods, like
Thread.sleep()
, take this request seriously, but methods are not required to pay attention to interruption. Methods that do not block but that still may take a long time to execute can respect requests for interruption by polling the interrupted status and return early if interrupted. You are free to ignore an interruption request, but doing so may compromise responsiveness.
One of the benefits of the cooperative nature of interruption is that it provides more flexibility for safely constructing cancelable activities. We rarely want an activity to stop immediately; program data structures could be left in an inconsistent state if the activity were canceled mid-update. Interruption allows a cancelable activity to clean up any work in progress, restore invariants, notify other activities of the cancellation, and then terminate.
Dealing with InterruptedException
If throwing
InterruptedException
means that a method is a blocking method, then calling a blocking method means that your method is a blocking method too, and you should have a strategy for dealing with InterruptedException
. Often the easiest strategy is to throw InterruptedException
yourself
Sometimes it is necessary to do some amount of cleanup before propagating the exception. In this case, you can catch
InterruptedException
, perform the cleanup, and then rethrow the exception.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 callinginterrupt()
to "reinterrupt" the current thread. At the very least, whenever you catchInterruptedException
and don't rethrow it, reinterrupt the current thread before returning.
catch (InterruptedException e) {
// Restore the interrupted status
<
strong
>Thread.currentThread().interrupt();</
strong
>
}
The worst thing you can do with
InterruptedException
is swallow it -- catch it and neither rethrow it nor reassert the thread's interrupted status. The standard approach to dealing with an exception you didn't plan for -- catch it and log it -- also counts as swallowing the interruption because code higher up on the call stack won't be able to find out about it. Implementing cancelable tasks
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
Noninterruptible blocking
Not all blocking methods throw
InterruptedException
. The input and output stream classes may block waiting for an I/O to complete, but they do not throw InterruptedException
, and they do not return early if they are interrupted. However, in the case of socket I/O, if a thread closes the socket, blocking I/O operations on that socket in other threads will complete early with a SocketException
. The nonblocking I/O classes in java.nio
also do not support interruptible I/O, but blocking operations can similarly be canceled by closing the channel or requesting a wakeup on the Selector
. Similarly, attempting to acquire an intrinsic lock (enter a synchronized
block) cannot be interrupted, but ReentrantLock
supports an interruptible acquisition mode.Noncancelable tasks
Some tasks simply refuse to be interrupted, making them noncancelable. However, even noncancelable tasks should attempt to preserve the interrupted status in case code higher up on the call stack wants to act on the interruption after the noncancelable task completes. Listing 6 shows a method that waits on a blocking queue until an item is available, regardless of whether it is interrupted. To be a good citizen, it restores the interrupted status in a finally block after it is finished, so as not to deprive callers of the interruption request. (It can't restore the interrupted status earlier, as it would cause an infinite loop --
BlockingQueue.take()
could poll the interrupted status immediately on entry and throws InterruptedException
if it finds the interrupted status set.)public Task getNextTask(BlockingQueue<
Task
> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
http://codepumpkin.com/interrupt-interrupted-isinterrupted-java-multithreading/
- interrupt() : When we call
loop.interrupt()
, an Interrupt status flag is set totrue
. - interrupted() : It is
static
method and checks the interrupt status flag of current thread. When we callinterrupted()
, the flag is returned and immediately set tofalse
.
https://stackoverflow.com/questions/1904072/java-difference-in-usage-between-thread-interrupted-and-thread-isinterrupted
http://www.xyzws.com/javafaq/what-are-the-differences-between-interrupted-and-isinterrupted-method-of-the-thread-class/57
http://www.xyzws.com/javafaq/what-are-the-differences-between-interrupted-and-isinterrupted-method-of-the-thread-class/57
What are the differences between interrupted() and isInterrupted() method of the Thread class?
- The interrupted() is a static method in Thread class that determines if the current thread has been interrupted. "The interrupted status of the thread is cleared by this method". Therefore, if a thread was interrupted, calling interrupted() once would return true, while a second call to it would return false until the current thread is interrupted again.
- The isInterrupted() is an instance method that tests if this thread instance has been interrupted. "The interrupted status of the thread is unaffected by this method".