I did several tests on the above.
I have experienced the following:
1) https://codegym.cc/quests/lectures/questcore.level06.lecture08
It seems the unofficial version always worked. It stopped the child thread in all cases.
Is this really true in all cases? Or was it just by coincidence?
2) https://codegym.cc/quests/lectures/questcore.level06.lecture09
The official version sometimes worked, sometimes it didn’t. It sometimes stopped the child thread, and not in other cases.
Why is this so unreliable?
3) The CG lecture says: "Nobody can guarantee that a thread will be stopped."
But what I have to do if I still want to be 100% sure to stop the thread?
Stopping threads: The unofficial version vs official version - 3 questions
Resolved
Comments (7)
- Popular
- New
- Old
You must be signed in to leave a comment
Jonaskinny Java Developer at Sandmedia
10 March 2022, 21:25
Only guarantees I know of to stop a thread cold ... System.exit() & physically pulling the plug.
The reason for the discrepancies could be arithmetic combined with processor speed, any other process load.
1000 milliseconds does not always equate to 4 * (1/4 of 1000) milliseconds if you have to do anything else while waiting for those increments. So if 4 x 250 + a little other processing time > 1000 you will see maybe 1 or 2 misses.
0
Nouser
3 April 2021, 09:12useful
2) cause you're not posting code I guess that you have problems with the interrupted state. Once an InterruptedException is thrown, the interrpted state is set back to false. if you have code like:
then interrupting the thread will cause the code to throw an InterruptedException (due to the sleep method) and therefore enter the catch block. The interrupted state is set to false again and when your code restarts the while loop the condition !current.isInterrupted() is true again and you endlessly continue your loop. But if you uncomment current.interrupt(); inside the catch block it works (re-reset the interrupted state). Or you could use a break statement instead or rearrange try-catch blocks.
1+2+3) "Nobody can guarantee that a thread will be stopped." Don't forget to read the sentences before and after that, especially: "Only a thread can stop itself."
Now have a look at my first example, if you call another method (that you do not have access to) inside the try block and that code has try-catch blocks, too and catches InterruptedExceptions without reseting the state of the interrupt, your code breaks. That's the text block before your qoute. And that's what CG means with your quote. You need to be careful and write your code that way, that the thread is able to stop itself. Cause nobody (external) can do that. You only can ask the thread to stop but the thread has to do that. +3
Gellert Varga
3 April 2021, 20:38
Thanks Nouser, I understood several things! :)
But unfortunately not each one...
I'm posting a code.
This code interrupts the child thread about 98 times out of 100 executing cases, but about 2 times not. (This ratio is varying.) These few exceptional times: it works like an infinite loop (prints out "Tick" endlessly).
Why doesn't this code work alike in all executing cases?
((I don't know if it matters: I tested the codes with JDK8 on Windows XP operating system, and not in IntelliJ IDEA but with command line execution.))
0
Nouser
3 April 2021, 21:56useful
This code should stop approx 1 in 100 times. The reason is the same I tried to explain above.
The main thread is sleeping. When it wakes up, it sets the isInterrupted flag of the clockThread to false.
In the meanwhile the clock thread is in its while loop. It is sleeping 250ms, printing Tick (let's say 1ms) and testing the while condition (if the isInterrupted flag is set to true, again we assume 1ms).
So the chances are extremly high that the clockThread is sleeping when the main thread is interrupting it. As said above, when you're interrupting while in the sleep method, then an exception is thrown an the isInterrupted flag is set back to false. Means later checks will fail and don't see the your interrupt request anymore.
Ok, the exception is thrown, we're in the catch block, do nothing here, lwave the catch block, reach the end of the while block and go back to the beginning of the while loop, test the condition !current.isInterrupted(), that's still true (the isInterrupted flag is, as mentioned, set back to false), and you continue the while loop endlessly. No ending of the thread even so you have asked to interrupt it.
Check my answer above again. You could either add a break statement inseide the catch block. Then if the InterruptedException is thrown (interrupt while sleeping), then you also would end the while loop and reach the end of the run method. Or you set the isInterrupted flag again. Same result, you leave the catch block, go the while condition, now the isInterrupted is true, the condition is false and you break the loop and reach the end of the while loop. Or, third possibility, have the while loop inside the try block, then the IE will kick you out of the while loop (cause the catch block is outside) and with leaving the catch block you reach the end of the run method, ending the thread.
You also could try to remove the sleep method. Then no exception is thrown and the flag is no set back to false. Then the whol condition always works.
+4
Gellert Varga
4 April 2021, 13:46
I understand well your explanation.
It is very logical, and thank you for the thorough explanation and the good solution-tips!:)
But you wrote:
"This code should stop approx 1 in 100 times"
this is just its opposite what i experienced in my attempts:
99 times was it stopped, and 1 times was not. If you don't belive, try it out:)
But finally i think i figured out why:
- main thread sleeped 1000ms,
- child thread sleeped 4x250ms,
and these are exactly equal.
I suppose that isInterrupted's checking and the printing takes much less time than 1ms. Hence probably in the most of case the main thread wakened concurrently with the child thread, when the sleep() method of the childthread just wasn't running. And that’s why thread-interrupting still worked well.
Am I correct?
After all this, I changed the sleep time of the main thread in my shared code above to 900ms.
Now at each execution of the program I got the endless cycle!:)
0
Nouser
4 April 2021, 15:56
I tried that already yesterday and it worked exactly as I described ( to be honest I just tried that 4 times ;) and all didn't stop). But that may be cause I'm sitting at my (slow) notebook and that doesn't run that proggie to the ms ;)
But good that things are clear to you now. Wish you peaceful holidays...
0
Gellert Varga
4 April 2021, 20:15
OK, thank you and I wish you too:)
0