Does calling Thread.interrupt() before a Thread.join() cause the join() to throw an InterruptedException immediately?
Does calling Thread.interrupt() before a Thread.join() cause the join() to throw an InterruptedException immediately?
No it will not throw. Only if the current thread that is calling the join()
method gets interrupted will join()
throw InterruptedException
. t.interrupt()
is interrupting the thread you just started, while t.join()
will only throw InterruptedException
if the thread that is doing the join-ing (maybe the main thread?) is itself interrupted.
Thread t = new Thread(someRunnable); t.start(); t.interrupt(); t.join(); // will _not_ throw unless this thread calling join gets interrupted
Also it is important to realize that interrupting a thread does not cancel it and join()
is not like a Future
in that it will return the exception the thread threw.
When you interrupt a thread, any calls the thread is making to sleep()
, wait()
, join()
, and other interruptible methods will throw InterruptedException
. If those methods are not called then the thread will continue running. If a thread does throw a InterruptedException
in response to being interrupted and then quits, that exception will be lost unless you you used t.setDefaultUncaughtExceptionHandler(handler)
.
In your case, if the thread is interrupted and finishes because it returns, then the join will finish -- it will not throw an exception. Common thread code to handle an interrupt properly is as follows:
public void run() { try { Thread.sleep(10000); } catch (InterruptedException e) { // a good pattern is to re-interrupt the thread when you catch Thread.currentThread().interrupt(); // another good pattern is to make sure that if you _are_ interrupted, // that you stop the thread return; } }
interrupt()
interrupts the thread you interrupted, not the thread doing the interrupting.
c.f.
Thread.currentThread().interrupt();t.join(); // will throw InterruptedException
interrupt()
will interrupt the execution of referenced thread, if its affected by sleep()
or wait()
or join()
.
- As there is no sleep /join /wait called on the main, this would only update the
interrupted
flag. - Verifies statement 1
t1.join()
pauses the execution ofMAIN thread
and allows t1 to execute beforeMAIN thread
proceeds. But, it seems like main internally checkThread.currentThread().isIntercepted()
and handles by raising the exception.- Verifies statement 3
- Verifies statement 3 and also, as exception has raised
intercepted
flag is set back to false
Sample Code:
t1.start(); System.out.println(Thread.currentThread().getName()+" isInterrupted(): "+Thread.currentThread().isInterrupted()); try { Thread.currentThread().interrupt(); // -- 1 System.out.println(Thread.currentThread().getName()+" isInterrupted(): "+Thread.currentThread().isInterrupted()); // -- 2 t1.join(); // -- 3 System.out.println("This is never called as exception is raised"); // -- 4 }catch(InterruptedException ex){ System.out.println(Thread.currentThread().getName()+" isInterrupted(): "+Thread.currentThread().isInterrupted()); -- 5 } System.out.println("Main continues");
Output:
main isInterrupted(): falseThread-0: 0main isInterrupted(): truemain isInterrupted(): falseMain continuesThread-0: 1Thread-0: 2Thread-0: 3
Above call is from main()
I hope this would help understand better 😊