Forums Register Login

A self interrupting thread.

+Pie Number of slices to send: Send
Hi,

I have a question regarding the sleep and interrupt mechanism of threads. I have understood that we can invoke the various overloaded Thread.sleep() methods from the run() method and they always put the current thread to sleep. I can have another thread issue an interrupt based on some logic. But I could not understand why would a thread need to interrupt itself. Clearly it has to be in running state for it to be able to interrupt itself. Or would that be wrong?

So if a thread is not sleeping/blocked, why would it ever need to interrupt itself? Can a blocked thread interrupt itself while it is blocked ( This question sounds weird to me also but I'm just making sure..).

Following is my test program.



In the above code where should I put what instruction to make obj1 a self interrupting thread? Or would that really be pointless? Could someone please advise.

Thanks in advance.
Chan.

1
+Pie Number of slices to send: Send
You may want to look into the thread life cycle and their states in a little more detail.

You may want to put a thread to sleep ... but interrupt/wake up itself ... sound possible but can it really be done practically?

Given 2 threads A and B, if A is currently inactive (sleep) and B does its stuff. When B is done it informs A to wake up (interrupt A) by calling notify.

Now just 1 thread A. Thread A does something and go to sleep. How can thread A get out of sleep (change state to active)? Call notify right? But where and will it actually work?



You may want to play around those thread methods wait, notify, sleep etc to see what happens.
1
+Pie Number of slices to send: Send
How can a thread interrupt itself when it's sleeping? The whole notion seems bizarre to me. Can you stab yourself when you are coma? No!

sure, you can add a methoid to a class that extends Thread that calls interrupt on the thread. You can call this method FROM another thread, but that's one thread interrupting another thread. It dpesn't matter that the interrupt method is on the target thread class. It's still the calling thread that is doing the interrupting.
1
+Pie Number of slices to send: Send

Technically, a thread can interrupt itself *before* calling the sleep() method. Calling the sleep() method with the interrupt flag set immediately throws the interrupted exception.

Of course, this is basically pointless, as the application can be coded to check and do the stuff in the interrupted exception handling code, instead of calling sleep() to throw that interrupt.

Henry
+Pie Number of slices to send: Send
Thanks, Henry. Actually yesterday I was browsing through oracle docs to see how a sleeping thread can get an interrupt ( how another thread issues an interrupt instruction ) and I came across http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt%28%29. I could not understand this part -->

Unless the current thread is interrupting itself, which is always permitted



It seemed very weird to me considering whatever little I knew about sleep method. I tried to google it myself but couldn't find anything useful. Thank God, it ain't worth spending anymore time.

You may want to play around those thread methods wait, notify, sleep etc to see what happens.



Know what. This thing is looking like a VERY, VERY complex game :-) At least that is what it seems like to me. It's so much of a relief now that there is one topic less in Threads' subject that I need to know. Knowing whatever I studied the day before and today and coding few sample programs has almost given me a headache. Just kidding :-)

Can you stab yourself when you are coma? No!


:-) :-) Exactly what I thought..

Thank you, guys.
Chan.
+Pie Number of slices to send: Send
K. Tsang,

I know though that I'll have to keep "playing" with these notify, notifyAll, Thread.sleep, wait, yield, join, and may be other things, if I don't wanna get a headache while really working on this stuff :-)

cheers,
Chan.
1
+Pie Number of slices to send: Send
Hi, Chan. There are not much reasons for thread to interrupt itself. Usually this occurs to properly notify "outer" code about thread termination when throwing InterruptedException is not appropriate or possible.

For example, we have a lengthy computations:

Our Job keeps thread "interrupted" status and BulkRunner can be properly interrupted. If Job will not interrupt itself, then BulkRunner will not see that termination and will continue processing. So we will get only one job cancelled instead of all jobs.

Same technique may be used to deal with an InterruptedException, but it is usually better to rethrow it (or just allow to escape) that write manual "reinterruptions" of current thread.
+Pie Number of slices to send: Send
Hi Maxim,

Thanks for your response. It seems like a great example. I'm trying to process it ( calls for some bit of reading on my part ).

Last but not the least - welcome to the Ranch.

Chan.




+Pie Number of slices to send: Send
Hi Maxim,

I tried to understand the code snippet you've posted. But I had few questions. For correctness and clarity, I have edited your code as follows. Let me know if the main method I have coded should be changed for the example to make sense. Or if I have incorrectly changed your code also, please let me know.



Actually I tried to find out some answers on my own but I couldn't understand much from what I have read.
If you could please explain me the following things, it'll make it easier for me to understand the whole thing behind interruption mechanism.

1. Would it be reasonable to assume that any thread that is in its run method and is executing some piece of code there has its interrupted bit set to false( the first time at least). Cause it is still running some piece of code in the run block. Only when it is interrupted ( for now let us assume by other threads ), its interrupted bit is set. It then throws an InterruptedException. So is the interrupted bit reset again by default so the next time the thread checks it or if is blocked or is sleeping, it can be interrupted again? Or would it be correct that the job of the interrupt() method is to only set the interrupted bit from false to true and from false to true only?

2. If we assume that a thread is currently checking the following condition in its run method-



shouldn't we assume that the call to heavy calculation stuff is already complete. Isn't that precisely why it would reach that check? Or let us say that the thread got interrupted somehow while performing those heavy duty calculations, wouldn't it then throw an Interrupted exception by default. But the compiler allows us to not have a try catch within our run. So doesn't it mean the heavy duty calls are not designed to throw an interrupted exception? The runAll method is also not interrupting the thread it is creating. It is only interrupting itself.

If you could explain in more details, I would certainly help me a lot.

Thanks..
Chan.


1
+Pie Number of slices to send: Send
Hi, Chan. I'll try to clarify it a bit.

Would it be reasonable to assume that any thread that is in its run method and is executing some piece of code there has its interrupted bit set to false( the first time at least)


Each new thread has interrupted bit set to false. But any running thread may have this bit set while executing some code. For example, thread may perform heavy calculations at the time of interruption. This flag should be treaded more or less like "this thread was requested to terminate but did not handled that request yet". So, it's perfectly legal for a thread to execute some code while this flag is set (by default this flag is not set).

Only when it is interrupted ( for now let us assume by other threads ), its interrupted bit is set.


Yes. Interrupted flag may be set only when a thread is interrupted. But there are cases when this flag will not be set and InterruptedException will be thrown instead.

It then throws an InterruptedException.


No, not always. There are only special cases when thread may throw an InterruptedExeption. Almost all cases are related with some form of waiting (wait/notify in objects and locks, Thread.sleep as kind timeout waiting, queue waiting, future waiting, etc...). And there may be interruptions within IO (there is an InterruptedIOException). Note, that usually IO is not interruptable (streams must be closed or timeouts should be set if possible). And if the InterruptedException is thrown, then "interrupted" flag is not set.

You may assume following procedure of interruption (it is executed as an atomic action):
  • Check, if thread is in "interruptible" state. Waiting threads are usually in interruptible state. Other cases includes interruptible IO like interruptible channels and selectors. You may see complete list of such conditions in javadoc for Thread.interrupt()
  • If thread is in an "interruptible" state, then InterruptedException (or it's IO counterpart) is raised in a target thread. Interrupted flag retains it's "false" value. So, you may treat it as a "handled interruption request" or "there is no unhandled interruption requests".
  • If thread is not in an "interruptible" state, then "interrupted" flag is set to true. No exception is thrown at this point. So, thread continues to run untill someone will handle that "pending request" for a termination.


  • Let's see, what can handle a "pending request". All methods, which can be interrupted (i.e. in which thread is in "interruptible" state) will clear interrupted flag and will throw an InterruptedException if that flag is set. So, that methods will not wait for a new termination (for example, during a waiting time) and will throw an exception immediately if thread interruption "was not handled so far". And you can manually check (and handle) requested interruption by calling Thread.interrupted (or only check by calling Thread.currentThread().isInterrupted()).

    So, when you call Thread.interrupt either interrupted flag will be set or InterruptedException will be thrown. Not both at the same time. And if interrupted flag is set, then some methods will throw InterruptedException immediately (and also will clear that flag).

    So is the interrupted bit reset again by default so the next time the thread checks it or if is blocked or is sleeping, it can be interrupted again?


    Yes, the "interrupted" flag is cleared. At this point we should assume that interruption will be "handled" by a code. Either there is a catch for an InterruptedException with a proper action, or some code explicitly checked and handled an interruption (it checked flag for a reason, not just of curiosity). So, thread may continue to run. For example, this thread may be reused in executor thread pools. But it is not correct to say that "flag is cleared to allow a thread be interrupted again". As noted above, if flag is not cleared, then first "interruptible" method call will throw InterruptedException. The true reason is like "allow thread to wait somewhere again".

    Or would it be correct that the job of the interrupt() method is to only set the interrupted bit from false to true and from false to true only?


    No. Flag will be set if and only if iInterruptedException or it's IO counterpart was not thrown. And exception can be thrown if and only if thread is executing an "interruptible" method at the time of an interruption. "Interruptible" methods are methods explicitly specified in Thread.interrupt's documentation. Method which declares an InterruptedException will not throw that exception by magic. It should explicitly create an exception itself when some condition is reached (for example, interrupted flag is set) or call some of the "interruptible" core methods.

    shouldn't we assume that the call to heavy calculation stuff is already complete. Isn't that precisely why it would reach that check?


    First statement is right. Second is not. Look three lines above in a code. We run that calculation in a loop. At this point only one iteration was complete. What about other 99999 iterations? So, we want to break a "for i" loop, not to terminate a heavy math calculation.

    Or let us say that the thread got interrupted somehow while performing those heavy duty calculations, wouldn't it then throw an Interrupted exception by default.


    No, it will not throw that exception. There are only specific places where an InterruptedException will be thrown. So in a heavy math code only interrupted flag will be set to true and no exceptions will be thrown. Of course, I assume, that there is no any waiting in that calculations, only a heavy math. And we need to check interruptions manually (nobody will handle them for us). If we skip check, then this method will be run until a normal termination having interrupted flag set. One intresting conclusion: you cannot interrupt heavy calculations (no IO, no waiting) unless they were designed to be interrupted.

    So doesn't it mean the heavy duty calls are not designed to throw an interrupted exception?


    You are right. Such calls usually are not designed to throw an interrupted exception. And they will not throw an InterruptedException unless required checks are hardcoded in them. There is no magic with interruptions. Interrupted flag will be set in a hope that someone will check it at some time later and nothing more.

    The runAll method is also not interrupting the thread it is creating. It is only interrupting itself.


    I see you changed a very important line . In your example there is no much reason to keep an interrupted flag because thread is terminated shortly after a method execution. In my example there is a reason. Let's assume, that runAll has my implementation and main has your implementation. Let's assume, that a thread was interrupted during a 50000 iteration (for i loop) of a first job. At this point this job will terminate and will reset interrupted flag to "true". One level above, in a BulkRunner.runAll we will also check "inetrrupted" flag and will discard remaining two jobs. If Job.run will not set interrupted flag back to true, then two other jobs will be run. So, we will get 250000 iterations instead of 50000.

    In summary (just repeating all above again):
  • InterruptedException may be thrown only at a specific places in a code like wait/notify methods.
  • If thread does not wait for anything, it have no chances to get InterruptedExceptions unless explicit checks for interruptions was coded. Thread may have interrupted flag set infinite amount of time if it does not try to wait for something.
  • We set "interrupted" flag back to true when we expect outer method to be able to handle interrupted status. So, it is necessary to check for an interruption at least two times in a call stack to have a reasonable example.


  • Hope that helps.
    You may also take a look into a source of PrintStream, PipedReader or PipedWriter classes. Search for InterruptedIOException in them. They repack "InterruptedIOException" into interrupted state to allow caller also handle that interruption.
    +Pie Number of slices to send: Send
    Hi Maxim,

    Thanks for your response. I'm trying to understand it..

    Just it might take me some time ( it's 1:20 AM in my country right now ). I will get back to you on this one. Thank you.

    Chan.
    +Pie Number of slices to send: Send
    So it turns out that a thread that is not executing a blocking method such as wait(), sleep(), join() etc ( which are designed to respond to external interrupts ) may increase its responsiveness to external interrupts by checking if another thread has set its interrupted status bit and then it may decide to interrupt itself so it can do some cleanup and cancel itself if it wishes to.

    This seems interesting. This also explains why a thread is not given the control to cancel another thread- it can merely set the status. Good threads might want to check and cancel themselves. This also explains why Thread.interrupted() which checks on this thread simultaneously resets the interrupted status bit while theadobj.isInterrupted() method does not have any control on changing the interrupted status ( cause it is another thread ).

    So far, so good. Took a while to understand. But in the end it was worth it.

    Thank you and greetings,
    Chan.

    I wanted to respond after some more reading. Hence the delay..
    +Pie Number of slices to send: Send
     

    I see you changed a very important line . In your example there is no much reason to keep an interrupted flag because thread is terminated shortly after a method execution. In my example there is a reason. Let's assume, that runAll has my implementation and main has your implementation. Let's assume, that a thread was interrupted during a 50000 iteration (for i loop) of a first job. At this point this job will terminate and will reset interrupted flag to "true". One level above, in a BulkRunner.runAll we will also check "inetrrupted" flag and will discard remaining two jobs. If Job.run will not set interrupted flag back to true, then two other jobs will be run. So, we will get 250000 iterations instead of 50000.



    This is the only part of your post that I could not understand. The only change I have made in runAll method is I have changed your direct call of run() method to start(). That would be a requirement, right? I don't see anything else changed. But is there something important that I'm missing? Because I couldn't understand the first two lines and stayed stuck there, I couldn't follow the next three lines. :-) And I might be missing something really, really important...

    Let me know...

    Thanks,
    Chan.
    1
    +Pie Number of slices to send: Send
    Yes, your understanding is correct. Good threads can handle interruptions.

    Try to examine a following scenarion by hand:

    Job1 and Job2 are two instances of a Job. Only three iterations. Only two jobs. Assume that interrupt happens between lines marked (1) and (2), sometime during an execution of Job1.calculate(1). What steps (and checks) will be executed when Job1 reinterrupts itself? What if it does not? There should be a difference (otherwise your forgot to reset an interrupted status somewhere). Try to make BulkRunner interruption-unaware (remove lines marked (4) and (8)). What happens now? How an execution will change if we run Job1 and Job2 in a separate threads? You should see that Thread.currentThread.interrupt() does not change execution in any significant way in a multithreaded scenario. This is the reason to have a direct call to run() method in the example.

    You should have at least two good pieces of code to leverage self-interruptions. Not two threads, but two pieces in a same thread. These pieces may call each other (initial scenario) or may execute in a sequence (scenario with lines (4) and (8) removed).

    In a real life BulkRunner may be a part of some framework. So we may try to leverage some shortcuts in it and reraise interrupted flag. It won't harm even if a framework is not interruption-aware . It just will run with an interrupted status set until it's normal termination.
    +Pie Number of slices to send: Send
    Hi Maxim,

    I'm not sure I understand. And I will understand if you're already fed up of explaining. :-) It ain't like I haven't worked on it. But from whatever I have tried, I am not able to appreciate the idea much. Perhaps it will make much more sense after I have worked on few more example cases or tried some more advanced concepts.

    Here is my logic ( and that is confined by my limited knowledge on the subject ).

    For the direct invocation of run case, since there was going to be just one main thread ( the main thread only like in any other non multi-threaded java app ), I tried to create an interrupt in the doHeavyCalculation() method as follows.



    I feel this sort of interrupt combinations are more like conditionals - if there is an interrupt ( and main would only issue this interrupt at some point in time - because that is the only thread we have ) don't process the rest of the first loop ( if there is a return ) or don't process the first and the second loop ( which would end the program ) or a part of the loop based on the combination of conditionals. There might be a case when you'd want to skip the rest of the loop for some other reason ( you've found what you were looking for sort of things ). But then I thought - aren't there better ways of achieving that.

    It made at least some sense to me in a multi-threaded case where I had multiple threads since these threads are involved in heavy duty calculations. Since these threads aren't invoking any blocking methods that can respond to interruptions, they could have these Thread.interrupted() checks followed by self interruptions constantly to give fair amount CPU to the other threads ( return or no return regardless ).

    And I'm quite sure I'm not understanding a little bit of what you've been trying to explain which is why there is a gap in my understanding. I think I'd better park this issue aside for a while so I can work on it later ( I have a couple of other 'parked aside' unsolved problems too that I will get back to later ).

    Once more, I greatly appreciate all your suggestions and help on the subject.

    Thanks,
    Chan.
    1
    +Pie Number of slices to send: Send
    I understand your confusion. Let's modify an example a bit. BulkRunner will run an execution in a same thread, but it will be run on it's own thread.

    There is a reason to interrupt jobs. And this reason is "outer" for the job itself.

    I feel this sort of interrupt combinations are more like conditionals


    You are right. The "interrupted" state is a kind of a condition. And there may be some kind of logic on several layers of the application (executors framework, some jobs, etc...).

    But then I thought - aren't there better ways of achieving that.


    Correct! Usually there are better ways to provide this conditional logic. And usually these other ways should be preferred. It is really hard to find an example where a self-interruption is the only reasonable choice.

    As I already wrote there is such self-interruption in a PrintStream. One of it's intentions is to "hide" all underlying IOExceptions. These PrintStreams (System.out and System.err) are sometimes used in debugging purposes (it don't force a user to write "throws IOException" just to have a trace facility inside a method). But they can sometimes detect an interruption under the hood: an underlying IO stream may throw InterruptedIOException. PrintStream can't throw this exception. It can't throw an InterruptedException also. It transforms this exception in "interrupted" status so an outer code (which performs main job) may detect this request and handle this accordingly. You definitely would not be happy if an interruption request is missed somewhere inside a library code and you code have no chance to handle it.

    It made at least some sense to me in a multi-threaded case where I had multiple threads since these threads are involved in heavy duty calculations. Since these threads aren't invoking any blocking methods that can respond to interruptions, they could have these Thread.interrupted() checks followed by self interruptions constantly to give fair amount CPU to the other threads ( return or no return regardless ).


    Sorry if I misleaded you. This checks can't provide some CPU for other thread. You should use Thread.yield for this purpose. The purpose of an example is to demonstrate some conditional logic (I use you words, they describes a situation pretty well) on two "levels" of a program for a one (and only one) interruption request. It is hard to provide a good example when all code is under your control because there are better ways to do that . We need some other restrictions to make this example more reasonable. Something like "already-defined" interfaces in frameworks, calls to a framework methods which calls our methods layers below, etc...
    +Pie Number of slices to send: Send
    Hi Maxim,

    Thanks for your response. I am working on this one. I will get back to you on this one after I have found answers to some basic concepts that are either incorrect/vague in my mind.

    Thanks,
    Chan.
    +Pie Number of slices to send: Send
    Sorry I am late by several months in responding to this one. But now I understand why a thread might need to interrupt itself sometimes. In other words I understand why an application may need to have threads that support their own interruption. Thanks everyone for your help.

    Chan.
    Getting married means "We're in love, so let's tell the police!" - and invite this tiny ad to the wedding:
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com


    reply
    reply
    This thread has been viewed 10543 times.
    Similar Threads
    closing thread and its childs
    Regarding non-static interrupt() and join() methods.
    Question from k&B's masterexam about yield()???????
    Countdown timer in java
    Threads - sleep() & notify()
    Why do we need awaitTermination?
    More...

    All times above are in ranch (not your local) time.
    The current ranch time is
    Mar 28, 2024 17:40:00.