Assume the below code is executed with a debugger so that we can predict the order of execution.
t1 -- Here task1 starts working on some long task.
t2 --- task2 gets blocked # Syncronized statement because task1 is holding lock.
t3 -- task2 is interrupted but its missed because task2 is using intrinsic locks and hence cannot be interrupted # synchronized. (Renenterant.lockInterruptible() would have thrown InterruptedExecption).
t4 --- task1 is interrupted. However despite of doing the complex task in try catch block, InterruptedExecption was never thrown. Why is that ?
Code:
public class TestInteruptibility {
public static Object lock = new Object();
public static boolean spin = true;
public static void main(String[] args) {
Thread task1 = new Thread(new Task(), "Task1");
Thread task2 = new Thread(new Task(), "Task2");
Thread notifier1 = new Thread(new Notifier(), "Notifier1");
task1.start();
task2.start();
task2.interrupt();
task1.interrupt();
notifier1.start();
}
}
class Task implements Runnable {
public void run() {
synchronized (TestInteruptibility.lock) {
System.out.println("Performing Long Task");
try {
while (TestInteruptibility.spin) {
}
System.out.println("Finsihed Performing Long Task");
TestInteruptibility.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("I got interrupted while i was waiting # wait()");
}
System.out.println("Ending Task");
}
}
}
class Notifier implements Runnable {
public void run() {
synchronized (TestInteruptibility.lock) {
System.out.println("Performing notification");
TestInteruptibility.lock.notify();
System.out.println("Ending notification");
}
}
}
Basically, what interrupt() does is to set a flag in the Thread object. And you need to check it with isInterrupted(). Then you can handle this interrupt signal. It won't throw an InterruptedException in this situation.
Besides, it can cause some methods, for example, Thread.sleep(), Object.wait(), to return immediately and throw an InterruptedException. And you can get and InterruptedException in this situation.
From Java Concurrency in Practice, 7.1.1. Interruption:
A good way to think about interruption is that it does not actually interrupt a running thread; it just requests that the thread interrupt itself at the next convenient opportunity. (These opportunities are called cancellation points.) Some methods, such as wait, sleep, and join, take such requests seriously, throwing an exception when they receive an interrupt request or encounter an already set interrupt status upon entry. Well behaved methods may totally ignore such requests so long as they leave the interruption request in place so that calling code can do something with it. Poorly behaved methods swallow the interrupt request, thus denying code further up the call stack the opportunity to act on it.
In your above code, you are not waiting/sleeping. So you have to check isInterrupted() and handle interrupt signal yourself in the while loop.
while (TestInteruptibility.spin) {
if (Thread.currentThread().isInterrupted()) {
break;
}
}
References:
why interrupt() not work as expected and how does it work
What does java.lang.Thread.interrupt() do?
You have a busy while loop, that holds the lock (and never ends, unless you change spin's value somewhere). I suppose that task1 is still in the loop, therefore it doesn't notice the interruption. Task2 can't acquire the lock, so it blocks.
The way Task is implemented, it can only be interrupted in during the wait command, which comes after the loop.
BTW: if you are using the spin data member in different threads, then it should probably be declared as volatile. For similar thread safety reasons, lock should be declared as final.
When you call method interrupt() the result depends on the this thread is doing currently. If it is blocked on some interruptable method such as Object.wait(), then it will be interrupted immediately, which means that InterruptedException will be throw inside the thread. If thread is not blocked, but is doing some calculations, or it is block on some non-interruptable method such as InputStream.read() then InterruptedException is not thrown, but interrupted flag is set on thread instead. This flag will cause InterruptedException next time thread will call some interruptable method, but not now.
In your case threads task1 and task2 are spinning in infinite empty loops and thus are not blocked on any interruptable methods, so when you call interrupt() on then, no InterruptedException is thrown inside that threads, but interrupted flag is just set. You probably should change your task code to look like this:
while (TestInteruptibility.spin && !Thread.interrupted ()) {
}
then you will exit from the loop as long as somebody will call interrupt on task thread.
Related
public class TwoThreads {
private static Object resource = new Object();
private static void delay(long n) {
try
{
Thread.sleep(n);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.print("StartMain ");
new Thread1().start();
delay(1000); //dealay 1
Thread t2 = new Thread2();
t2.start();
delay(1000); // delay 2
t2.interrupt(); //here its throwing exception
delay(1000); //delay 3
System.out.print("EndMain ");
}
static class Thread1 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Startl ");
delay(6000);
System.out.print("End1 ");
}
}
}
static class Thread2 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Start2 ");
delay(2000);
System.out.print("End2 ");
}
}
}
}
I just got confused here why t2.interrupt() is not throwing exception when t2 is waiting to acquire lock on resource object and interrupt() method might throw security exception then why compiler still allowing us to execute it without putting it into try catch block.
A synchronized block doesn't throw an InterruptedException and interrupting a thread blocking while attempting to acquire a monitor this way doesn't do anything.
If you want this functionality you need to use a Lock which has lockInterruptibly(), though this is not often used.
Acquires the lock unless the current thread is interrupted. Acquires
the lock if it is not held by another thread and returns immediately,
setting the lock hold count to one.
If the current thread already holds this lock then the hold count is
incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread becomes
disabled for thread scheduling purposes and lies dormant until one of
two things happens:
The lock is acquired by the current thread; or Some other thread
interrupts the current thread. If the lock is acquired by the current
thread then the lock hold count is set to one.
If the current thread:
has its interrupted status set on entry to this method; or is
interrupted while acquiring the lock, then InterruptedException is
thrown and the current thread's interrupted status is cleared.
From Thread#interrupt():
If none of the previous conditions hold then this thread's interrupt status will be set.
If you checked t2.interrupted(), you'd see a true result, but the thread is blocking on entering the synchronized block, which doesn't trigger an InterruptedException.
A call to interrupt() may throw a SecurityException if the application's environment has set up restrictions on which threads can interact with others, but this doesn't apply in your simple example.
The question is unclear but I guess I understood it correct so I am attempting to answer.
syncrhonized blocks are NOT responsive to interrupts.
For that you can use explicit locks Lock, which has a method lockInterruptibly() which is responsive to interrupts.
lockInterruptibly() in Lock Interface
java.lang.Thread.interrupt() means Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
you have called sleep() on t2. that is the reason of getting interruptedException.
thread.join() will call thread.wait(), but who and when notifies (either with thread.notify() or notifyAll()) the thread.wait()?
As we know, thread join will wait for the thread to be completed, but who calls notify on it?
As for jdk7 for linux, you can get the answer from the source code of openjdk.
/jdk7/hotspot/src/os/linux/vm/os_linux.cpp
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
static void *java_start(Thread *thread) {
...
thread->run();
return 0;
}
and when start thread in java, the thread will be instanceof JavaThread.
/jdk7/hotspot/src/share/vm/runtime/thread.cpp
void JavaThread::run() {
...
thread_main_inner();
}
void JavaThread::thread_main_inner() {
...
this->exit(false);
delete this;
}
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
...
// Notify waiters on thread object. This has to be done after exit() is called
// on the thread (if the thread is the last thread in a daemon ThreadGroup the
// group should have the destroyed bit set before waiters are notified).
ensure_join(this);
...
}
static void ensure_join(JavaThread* thread) {
// We do not need to grap the Threads_lock, since we are operating on ourself.
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "java thread object must exist");
ObjectLocker lock(threadObj, thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
// Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED.
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
// Clear the native thread instance - this makes isAlive return false and allows the join()
// to complete once we've done the notify_all below
java_lang_Thread::set_thread(threadObj(), NULL);
lock.notify_all(thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
}
so lock.notify_all(thread) will notify all threads whose wait for the thread to finish.
Edit:
Oh, you are talking about inside of the Thread object itself. Inside of join() we do see a wait(). Something like:
while (isAlive()) {
wait(0);
}
The notify() for this is handled by the Thread subsystem. When the run() method finishes, the notify() is called on the Thread object. I'm not sure if the code that actually calls notify() can be seen -- it seems to be done in native code.
No user code needs to call notify() on that Thread object. The Java Thread code handles this internally. Once the thread finishes, the join() call will return.
For example, the following code will execute fine and the join() call will return fine without any wait() or notify() calls.
Thread thread = new Thread(new Runnable() {
public void run() {
// no-op, just return immediately
}
});
thread.start();
thread.join();
It is important to note that this behavior should probably not be relied upon. The notify() call is internal to the thread system. You should use join() if you are waiting for a thread to finish.
Given the following Java code:
public class Test {
static private class MyThread extends Thread {
private boolean mustShutdown = false;
#Override
public synchronized void run() {
// loop and do nothing, just wait until we must shut down
while (!mustShutdown) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Exception on wait()");
}
}
}
public synchronized void shutdown() throws InterruptedException {
// set flag for termination, notify the thread and wait for it to die
mustShutdown = true;
notify();
join(); // lock still being held here, due to 'synchronized'
}
}
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
try {
Thread.sleep(1000);
mt.shutdown();
} catch (InterruptedException e) {
System.out.println("Exception in main()");
}
}
}
Running this will wait for one second and then properly exit. But that is unexpected to me, I expect a dead-lock to happen here.
My reasoning is as follows: The newly created MyThread will execute run(), which is declared as 'synchronized', so that it may call wait() and safely read 'mustShutdown'; during that wait() call, the lock is released and re-acquired upon returning, as described in the documentation of wait(). After one second, the main thread executes shutdown(), which is again synchronized as to not access mustShutdown at the same time as it's being read by the other thread. It then wakes up the other thread via notify() and the waits for its completion via join().
But in my opinion, there's no way that the other thread can ever return from wait(), since it needs to re-acquire the lock on the thread object before returning. It cannot do so because shutdown() still holds the lock while inside join(). Why does it still work and exit properly?
join() method internally calls wait() which will result in releasing of the lock(of Thread object).
See the code of join() below:
public final synchronized void join(long millis)
throws InterruptedException {
....
if (millis == 0) {
while (isAlive()) {
wait(0); //ends up releasing lock
}
}
....
}
Reason why your code sees this and not seen in general:: The reason why your code see this and not is not observed in general, is because the join() method waits() on Thread object itself and consequently relinquishes lock on the Thread object itself and as your run() method also synchronizes on the same Thread object, you see this otherwise unexpected scenario.
The implementation of Thread.join uses wait, which lets go of its lock, which is why it doesn't prevent the other thread from acquiring the lock.
Here is a step-by-step description of what happens in this example:
Starting the MyThread thread in the main method results in a new thread executing the MyThread run method. The main Thread sleeps for a whole second, giving the new Thread plenty of time to start up and acquire the lock on the MyThread object.
The new thread can then enter the wait method and release its lock. At this point the new thread goes dormant, it won't try to acquire the lock again until it is woken up. The thread does not return from the wait method yet.
At this point the main thread wakes up from sleeping and calls shutdown on the MyThread object. It has no problem acquiring the lock because the new thread released it once it started waiting. The main thread calls notify now. Entering the join method, the main thread checks that the new thread is still alive, then waits, releasing the lock.
The notification happens once the main thread releases the lock. Since the new thread was in the wait set for the lock at the time the main thread called notify, the new thread receives the notification and wakes up. It can acquire the lock, leave the wait method, and finish executing the run method, finally releasing the lock.
The termination of the new thread causes all threads waiting on its lock to receive a notification. This wakes up the main thread, it can acquire the lock and check that the new thread is dead, then it will exit the join method and finish executing.
/**
* Waits at most <code>millis</code> milliseconds for this thread to
* die. A timeout of <code>0</code> means to wait forever.
*
* #param millis the time to wait in milliseconds.
* #exception InterruptedException if any thread has interrupted
* the current thread. The <i>interrupted status</i> of the
* current thread is cleared when this exception is thrown.
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
To complement the other answers: I see no mention of join() releasing any locks in the API-documentation, so this behavior is actually implementation-specific.
Learn from this:
don't subclass Thread, instead use a Runnable implementation passed to your thread object.
don't synchronize/wait/notify on objects you don't "own", e.g. where you don't know who else might synchronize/wait/notify on it.
I wrote a thread, it is taking too much time to execute and it seems it is not completely done. I want to stop the thread gracefully. Any help ?
The good way to do it is to have the run() of the Thread guarded by a boolean variable and set it to true from the outside when you want to stop it, something like:
class MyThread extends Thread
{
volatile boolean finished = false;
public void stopMe()
{
finished = true;
}
public void run()
{
while (!finished)
{
//do dirty work
}
}
}
Once upon a time a stop() method existed but as the documentation states
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
That's why you should have a guard..
The bad part about using a flag to stop your thread is that if the thread is waiting or sleeping then you have to wait for it to finish waiting/sleeping. If you call the interrupt method on the thread then that will cause the wait or sleep call to be exited with an InterruptedException.
(A second bad part about the flag approach is that most nontrivial code is going to be utilizing libraries like java.util.concurrent, where the classes are specifically designed to use interruption to cancel. Trying to use the hand rolled flag in a task passed into an Executor is going to be awkward.)
Calling interrupt() also sets an interrupted property that you can use as a flag to check whether to quit (in the event that the thread is not waiting or sleeping).
You can write the thread's run method so that the InterruptedException is caught outside whatever looping logic the thread is doing, or you can catch the exception within the loop and close to the call throwing the exception, setting the interrupt flag inside the catch block for the InterruptedException so that the thread doesn't lose track of the fact that it was interrupted. The interrupted thread can still keep control and finish processing on its own terms.
Say I want to write a worker thread that does work in increments, where there's a sleep in the middle for some reason, and I don't want quitting the sleep to make processing quit without doing the remaining work for that increment, I only want it to quit if it is in-between increments:
class MyThread extends Thread
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
doFirstPartOfIncrement();
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
// restore interrupt flag
Thread.currentThread().interrupt();
}
doSecondPartOfIncrement();
}
}
}
Here is an answer to a similar question, including example code.
You should not kill Thread from other one. It's considered as fairly bad habit. However, there are many ways. You can use return statement from thread's run method.
Or you can check if thread has already been interrupted and then it will cancel it's work. F.e. :
while (!isInterrupted()) {
// doStuff
}
Make a volatile boolean stop somewhere. Then in the code that runs in the thread, regularly do
if (stop) // end gracefully by breaking out of loop or whatever
To stop the thread, set stop to true.
I think you must do it manually this way. After all, only the code running in the thread has any idea what is and isn't graceful.
You need to send a stop-message to the Thread and the Thread itself needs to take action if the message has been received. This is pretty easy, if the long-running action is inside loop:
public class StoppableThread extends Thread {
private volatile boolean stop = false;
public void stopGracefully() {
stop = true;
}
public void run() {
boolean finished = false;
while (!stop && !finished) {
// long running action - finished will be true once work is done
}
}
}
For a thread to stop itself, no one seems to have mentioned (mis)using exception:
abstract class SelfStoppingThread extends Thread {
#Override
public final void run() {
try {
doRun();
} catch (final Stop stop) {
//optional logging
}
}
abstract void doRun();
protected final void stopSelf() {
throw new Stop();
}
private static final class Stop extends RuntimeException {};
}
A subclass just need to override doRun() normally as you would with a Thread, and call stopSelf() whenever it feels like it wants to stop. IMO it feels cleaner than using a flag in a while loop.
My question is related to all those methods(including Thread.sleep(...)) which throw InterruptedException.
I found a statement on Sun's tutorial saying
InterruptedException is an exception that sleep throws when another thread interrupts the current thread while sleep is active.
Is that means that the interrupt will be ignored if the sleep is not active at the time of interrupt?
Suppose I have two threads: threadOne and threadTwo. threadOne creates and starts threadTwo. threadTwo executes a runnable whose run method is something like:
public void run() {
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
: // In the middle of two sleep invocations
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
}
After thread creation, threadOne interrupts threadTwo. Suppose the threadTwo is in the middle of two sleep invocations at the time of interrupt (when no sleep method was active), then will the second sleep method throw InterrupteException as soon as it is invoked?
If not, then will this interrupt will be ignored forever?
How to be sure that threadTwo will always know about the interrupt (doesn't matter whether its one of the sleep method is active or not)?
From javadoc:
If this thread is blocked in an
invocation of the wait(), wait(long),
or wait(long, int) methods of the
Object class, or of the join(),
join(long), join(long, int),
sleep(long), or sleep(long, int),
methods of this class, then its
interrupt status will be cleared and
it will receive an
InterruptedException.
If this thread is blocked in an I/O
operation upon an interruptible
channel then the channel will be
closed, the thread's interrupt status
will be set, and the thread will
receive a ClosedByInterruptException.
If this thread is blocked in a
Selector then the thread's interrupt
status will be set and it will return
immediately from the selection
operation, possibly with a non-zero
value, just as if the selector's
wakeup method were invoked.
If none of the previous conditions
hold then this thread's interrupt
status will be set.
This means that you have to check the interrupted status to be sure your thread knows about the interruption. This can be done with two methods: isInterrupted() and interrupted(). The last one clear the interrupted status.
Something like this:
while(!Thread.interrupted()) {
...
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
}
On Sun's Windows JDK, the thread will in fact throw InterruptedException when entering sleep():
public static final void main(String args[]) throws Exception {
final Thread main = Thread.currentThread();
Thread t = new Thread() {
#Override
public void run() {
main.interrupt();
}
};
t.start();
t.join();
Thread.sleep(1000);
System.out.println("Not interrupted!");
}
The API documentation of sleep() can be interpreted to mean that this is mandatory behaviour:
throws InterruptedException - if any
thread has interrupted the current
thread. The interrupted status of the
current thread is cleared when this
exception is thrown.
But that's not very clear, so I wouldn't depend on it and instead check isInterrupted() manually.
The Java documentation is a tad misleading. If the interrupted status of a thread is set, calling sleep() on that thread will cause an InterruptException to be thrown immediately.
This applies even if the thread was interrupted before sleep() was called.
As stated above, though, you can also check with Thread.isInterrupted() if you want to handle interrupts yourself.
The InterruptionException is only of interest during the sleep of the thread. It won't be thrown by the later sleep() call if the thread has been interupted anywhere before. Only the interuption at the time of the sleep() does matter because it breaks exactly that sleep() call.