Reputation: 327
In our application we have threads doing a specific action. On receive of an event, we need to interrupt those threads in progress. These threads would check their interrupt status by calling "Thread.currentThread().isInterrupted()", if it is interrupted, then the thread stops by returining from run method.
Problem we are seeing now is these threads can wait() on a object. If the thread is interrupted while wait() on an object, the Threads interrupt status is reset and InterruptedException is thrown.
Since 1) we have many places where the thread can wait on an object 2) the methods of other objects which the thread access can wait on an object
we have decided to override the interrupt() & isInterrupted() method. The code would look something like
public class MyThread extends Thread {
private boolean isInterrupted = false;
@Override
public void interrupt() {
isInterrupted = true;
super.interrupt();
}
@Override
public boolean isInterrupted() {
return isInterrupted;
}
public void run() {
.........
.........
try {
object1.wait();
} catch (InterruptedException e) {
/* if interrput() is not overrided, the interrupted flag
would be reset */
}
if(Thread.currentThread().isInterrupted()) {
/* if interrupt is not overrided, isInterrupted would return
false and the thread would continue to run. */
return;
}
object2.method1(); // method1() can also wait on another object
/* In method1() also we would need to check isInterrupted and get out
quickly as soon as possible. This method1() will also be used by
other threads which will not be interrupted. */
if(Thread.currentThread().isInterrupted()) {
return;
}
.........
.........
}
}
So my questions are
1) Is overriding interrupt() and isInterrupted() as above is a good practice to code?
2) While overriding interrupt() should we maintain the same behavior i.e. throw interrupted and other exceptions as stated in the java doc of interrupt() method in Thread class? Actually we need the threads that are waiting to be interrupted but the interrupted flag to be set.
3) What about Thread.interrupted() method which is static. With the above overriding we shouldn't use this method right?
Upvotes: 2
Views: 5569
Reputation: 3364
As per your comments , you are forced to override the methods due to third party jar's is not setting Interrupted status Again.
In General as @Holger mentioned , The method catching InterruptedException
should restore the state.
if the third party jar's is not setting status back why don't you reset the flag after third party method call ?
thirdPartyInstance.method1();
if (Thread.currentThread().isInterrupted()){
Thread.interrupted();
}
So that you can use your Jobs as Runnable
instead of Actual Thread
( You don't need to override the methods) and you can use the way Thread.currentThread().isInterrupted()
to stop your thread.
Finally- if you plan to continue by extend Thread and overriding those methods,
Modify your isInterrupted()
method as
@Override
public boolean isInterrupted() {
return isInterrupted || super.isInterrupted();
}
To cover if the thread status cleared by Thread.interrupted();
some where.
Upvotes: 0
Reputation: 298539
First of all, overriding these methods is a very bad idea.
Second, I don’t get why you are making your life that hard:
try {
doSomethingThatCanBlock();// e.g. wait()
}
catch(InterruptedException ex) {
Thread.currentThread().interrupt(); // restore interrupt state
}
Now, the next time you check the interrupted state of your Thread
it will tell you the appropriate state. That’s it.
Upvotes: 9
Reputation: 46492
If the thread is interrupted while wait() on an object, the Threads interrupt status is reset and InterruptedException is thrown.
IMHO this sentence shows that you don't want any interrupt at all. Interrupt can be used to abort thread's execution and you don't seem to want it. Pass some messages instead... if you want to have it flexible, try an EventBus. It allows you to send messages to program parts the sender knows nothing about.
Maybe watching some global variables1 is what you need. Note that using Thread.interrupt
is dealing with global variables too (and gets rather unusable in face of a ThreadPool
).
1 Packed into a singleton or alike.
Upvotes: 0