I do not understand why the thread does not throw an InterruptedException when interrupted itself.
I'm trying with following snippet:
public class InterruptTest {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
#Override
public void run() {
Thread.currentThread().interrupt();
}
} }
In the API docs it says on the interrupt() method:
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 Thread.join(), Thread.join(long), Thread.join(long, int), Thread.sleep(long), or Thread.sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
I know this is an old question, but I think the answers above are actually not quite correct. (except #Skylion's, which doesn't really address the question...) :)
Thread.interrupt() does not throw any exceptions by itself. It does two things: First it simply sets an internal interrupted-flag and then it checks if the thread that it was called on is currently blocking on an activity like wait(), sleep(), or join(). If it finds one, then it wakes up that method and causes that method to throw the exception inside the thread it was called on (not from).
In the case where you call interrupt() from the thread itself, that thread obviously can't itself be currently blocking on one of those calls as it is currently executing your interrupt() call. So, only the internal interrupted-flag is set and no exception is thrown at all.
The next time you call one of the blocking methods (like sleep() in #OldCurmudgeon's example) from that thread, that method will notice the interrupted-flag and throw the InterruptedException.
If you don't ever call any of those methods, your thread will simply continue running until it terminates some other way and will never throw an InterruptedException. This is true even if you call interrupt() from a different thread.
So, to notice that your thread has been interrupted, you either need to frequently use one of the blocking methods that throws an InterruptedException and then quit when you receive one of those exceptions, or you need to frequently call Thread.interrupted() to check the internal interrupted-flag yourself and quit if it ever returns true. But you are also free to simply ignore the exception and the result from Thread.interrupted() completely and keep the thread running. So, interrupt() might be a little bit ambiguously named. It doesn't necessarily "interrupt" (as in "terminate") the Thread at all, it simply sends a signal to the thread that the thread can handle or ignore as it pleases. Much like a hardware interrupt signal on a CPU (which is probably where the name comes from).
To have the exception be thrown by the join() method in your main thread, you need to call interrupt() on that thread, rather than on MyThread, like so:
public static void main(String[] args) {
MyThread t = new MyThread();
t.setDaemon(true); // Quit when main thread is done
t.start();
try {
t.join();
} catch (InterruptedException ex) {
System.out.println("Now it works:");
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
private final Thread parentThread;
public MyThread() {
parentThread = Thread.currentThread();
}
#Override
public void run() {
parentThread.interrupt(); // Call on main thread!!!
while (true); // Keep thread running (see comments)
}
}
See #markus-a's answer for what should have been the accepted answer here.
(Mine should be deleted, but I can't do that while it's accepted).
Exceptions are always thrown on their own thread. You have two different threads: your main thread and the one you created. There's no way the exception thrown in MyThread can be caught in the main one.
Why interrupt the thread at all? Just use
return;
You're just being too quick - try this:
private static class MyThread extends Thread {
#Override
public void run() {
try {
Thread.currentThread().interrupt();
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, "Oops", ex);
}
}
}
I get:
Oct 04, 2013 12:43:46 AM test.Test$MyThread run
SEVERE: Oops
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$MyThread.run(Test.java:36)
note that you cannot propagate the exception out of the run method because run does not throw any exceptions.
Related
Code as below:
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
thread.interrupt();
System.out.println(thread.isInterrupted());
}
}
Sometimes System.out.println(thread.isInterrupted()); prints true while sometimes prints false !
So how can the code higher up the call stack see that an interrupt was issued as described in JCIP 5.4?
That's the way to go, but your code faces a race condition. Your main thread executes thread.isInterrupted() immediately after calling thread.interrupt().
The documentation states that
If this thread is blocked in an invocation of [...] or sleep(long, int) methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
Give thread thread a fair chance to catch the exception and to set the interrupt status, that is join the thread or wait a moment, at least.
Hi i am studying and playing with thread in java. i read in a book that Thread object and Running Thread is not same thing.even the thread complete it's run method running thread goes into dead state i even check that with isAlive() method. i want to know that if both are different then the following code is not working as per i understand.
public class Main {
public static void main(String[] args) throws ParseException {
Student s = new Student();
Thread t = new Thread(s);
t.start();
t.run();
t.run();
t.run();
t.run();
t.run();
}
}
class Student implements Runnable {
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
it only shows this output.
main
Thread-0
main
or this
Thread-0
main
from this result i understand that after thread complete it's run method. Running thread goes into dead State and calling on Thread obj method no working.but i couldn't understand the reason behind because Thread object is skill reference and what about the other methods of Thread class.
like
yield()?
start()?
here is another scenario for clear understanding what i said
public class Main {
public static void main(String[] args) throws ParseException {
Student s = new Student();
Thread t = new Thread(s);
t.start();
if (!t.isAlive()) {
t.start();
}
}
}
class Student implements Runnable {
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
documentation said if we call start method on Thread t object then it will throw java.lang.IllegalThreadStateException. but the above code working fine.
i am very confused about which methods of Thread class rely on Running thread and which for thread object. i hope you understand the problem.
thanks in advance?
Right after starting the thread by t.start(), this condition:
if (!t.isAlive())
is veeeeeeeeeeeeeeeeeeery unlikely to be met--because started thread doesn't block. That is why it just skips (because t.isAlive() == true) and goes further without an exception.
You can do it on both ways. It's pretty much the same. You should start the thread in your first code file just with a simple
t.start();
I'd remove all the t.run() from your above code, because you are creating a new Thread object with your implemented inner class.
In your first attempt you never restarted the thread:
t.start();
t.run();// does not restarts the thread, it simply makes synchronous call the run(), hence you don't get the exception
t.start();// add this line, to restart the thread and get the exception
On second attempt, the condition fails as the thread is likely to start and is alive, as per your condition thread must not be alive and it fails to restart the thread.
t.start();
t.join();// add this line, it allows thread to complete first
if (!t.isAlive()) {
t.start();
}
P.S.
In order to start a thread make call to start() which will cause async call to run(). If you make call to run(), it won't start as thread, it will be synchronous call like normal method invocation.
In the first example you provided, the cause for the program not displaying a count of thread names equal to your t.start() + t.run() calls is the fact that after a thread is dead, you cannot call on it start() or run() again. It's dead. The reason there are 3 outputs is likely because until t.start() enters in dead state, the other 2 calls manage to perform.
In the second example, you should be aware that when a start() is called, the thread state is put on alive. Anyway, in a concurrent environment you cannot rely on operations call sequence if synchronized isn't involved, but, from the result you get, it seems that t.start() is called before the t.isAlive() check.
Hope to help.
i read in a book that Thread object and Running Thread is not same thing.
Right, a "thread" is an execution of your code. A Thread is a Java object that you can use to create and mananage the life-cycle of a "thread". The "thread" is not created until you call the Thread object's .start() method, and the Thread object can continue to exist even after the "thread" has finished its work and disappeared.
To get this code to compile, I can either:
Put my call to Thread.sleep() in a try/catch block, or
Have printAll() declare that it can throw an InterruptedException.
Why do I have to do this?
class Test {
public static void main( String[] args ) {
printAll( args );
}
public static void printAll( String[] line ) {
System.out.println( lines[ i ] );
Thread.currentThread().sleep( 1000 ):
}
}
(Sample code from Kathy Sierra's SCJP book.)
I know that the exception which Thread.sleep() throws is a checked exception, so I have to handle it, but in what situation does Thread.sleep() need to throw this exception?
If a method is declared in a way that it can throw checked exceptions (Exceptions that are not subclasses of RuntimeException), the code that calls it must call it in a try-catch block or the caller method must declare to throw it.
Thread.sleep() is declared like this:
public static void sleep(long millis) throws InterruptedException;
It may throw InterruptedException which directly extends java.lang.Exception so you have to catch it or declare to throw it.
And why is Thread.sleep() declared this way? Because if a Thread is sleeping, the thread may be interrupted e.g. with Thread.interrupt() by another thread in which case the sleeping thread (the sleep() method) will throw an instance of this InterruptedException.
Example:
Thread t = new Thread() {
#Override
public void run() {
try {
System.out.println("Sleeping...");
Thread.sleep(10000);
System.out.println("Done sleeping, no interrupt.");
} catch (InterruptedException e) {
System.out.println("I was interrupted!");
e.printStackTrace();
}
}
};
t.start(); // Start another thread: t
t.interrupt(); // Main thread interrupts t, so the Thread.sleep() call
// inside t's run() method will throw an InterruptedException!
Output:
Sleeping...
I was interrupted!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at Main$1.run(Main.java:13)
One Thread can communicate with and interact with another Thread, and one way that it can do it is by interrupting it: if t is another Thread, you can call t.interrupt() to ask it politely to stop what it's currently doing. This is in particular something you might want to do if t is sleeping: you might want to wake it up. What it does is to cause an InterruptedException in t's Thread.sleep() method, so that it can catch it and respond. Because of this, any time you use Thread.sleep() to make the current thread go to sleep, you have to deal with the possibility of an InterruptedException in case another thread decides to wake it up.
In your case, you've only got one Thread, so you know that there can't be an InterruptedException from elsewhere in your code. But it's a not uncommon thing to want to do in multi-threaded code.
class Demo extends Thread{
public void run() {
for (int i = 0; i <10; i++) {
system.out.println("hello Ziyad");
thread.sleep(1000);
}} }
public class Threddemo{
public static void main(string[] args) throws interruptedexception {
Demo t=new Demo();
Demo t2=new Demo();
t.start();
t2.start();
}}
Suppose We have two Thread t and t2 and t is executing while executing, t2 came and t2 is also start executing but t is not finish yet
there the thread get interrupted and you lose your data.In above example t thread is running and when in spleeping mode, and there t2 came
and start executing suddenly t get up but t2 is running this is chance of interruptedexception and data lose to avoid this we use interruptedexception
Is it sufficient to wrap contents of run method inside a while loop that checks if THread is interrupted for making any Thread interruptable
public void run () {
while (!Thread.interrupted()) {
do something.
}
}
How does a thread support its own interruption? This depends on what
it's currently doing. If the thread is frequently invoking methods
that throw InterruptedException, it simply returns from the run method
after it catches that exception.
Reference documentation
For a example if your thread goes for sleep bettween work then it is better to catch InterruptedException.
public void run(){
while(true)
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
If your thread runs for long time you can check periodically invoke Thread.interrupted, which returns true if an interrupt has been received.
interrupted() is static method to check the current thread is interrupted or not. isInterrupted() is an instance to check the Thread objects called on.
For Present Thread use
if(!(Thread.interrupted())){//do something}
When Thread object called use if(myThread.isInterrupted()){//do something
}
Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)
Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Some things to be aware of:
Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.
Note that there is no need for a separate boolean flag.
The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.
Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.
Some observations about the posted code:
The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.
The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.
Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Good way to do it would be to use a boolean flag to signal the thread.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.