I have implemented a connection check thread. When I have created a heavy traffic I have realized that there are many "ConnWatchdogThread" instances.
I think "continue" statement triggers the interrupted thread live and in that case new "ConnWatchdogThread" is created. If so how this happen? How thread is interrupted?
private class ConnWatchdog extends Thread {
public ConnWatchdog(){
setName("ConnWatchdogThread");
}
private void checkConnections() {
//connection check
}
#Override
public void run() {
while (true) {
try {
Thread.sleep(checkPeriod);
} catch (InterruptedException e) {
// e.prinstackTrace()
continue;
}
try {
this.checkConnections();
} catch (Throwable t) {
}
}
}
}
Interruption happens when the interrupt method on the thread is called. It's not shown in your example what is doing the interrupting. Here's an example of using interrupt.
The continue advances control to the next iteration of the loop. So when something calls interrupt on your thread while it's sleeping, it bails out of the sleep (clearing the interrupt flag), then the continue sends it back to the top of the loop and it goes to sleep again, which seems pointless.
Nothing in the code shown causes a new thread to be created.
It would be more normal to use the interruption to exit the while loop and cause the thread to terminate. Using interruption for things other than thread-cancellation is not recommended (Java Concurrency in Practice, 7.1, page 138):
There is nothing in the API or language specification that ties interruption to any specific cancellation semantics, but in practice, using interruption for anything but cancellation is fragile and difficult to sustain in larger applications.
The only way to create a new Thread is with new Thread(...). Your continue is causing interrupt to be ignored and for it to sleep a little longer.
Interrupt is a special flag (but basically still just a flag) When you interrupt() a Thread it will cause some methods to throw an InterruptedException even if they are blocking. Once triggered the flag is reset.
It is generally a bad idea to ignore exception/error thrown esp in code which is not working perfectly.
Your not showing the code that uses this class. No way to say what is making the instances. Continue wont do it. In fact can remove continue from your code in the ConnWatchdog first try-catch and it will work just fine.
Post your code that is calling ConnWatchdog / instantiating it to see full picture. Is that in a loop?
Related
Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged
I read concurency in practice. Now I want to understand how to handle InterrruptedException
Advices from book:
- Propagate the exception (possibly after some task-specific cleanup),
making your method an interruptible blocking method, too; or
- Restore the interruption status so that code higher up on the call stack can
deal with it.
- Only code that implements a thread's interruption policy
may swallow an interruption request. General-purpose task and library
code should never swallow interruption requests.
First two statements are clear for me but I don't understand third. Can you clarify this? Providing example will preferably.
update(thanks Shubham for the link )
The one time it is acceptable to swallow an interrupt is when you know
the thread is about to exit. This scenario only occurs when the class
calling the interruptible method is part of a Thread, not a Runnable
or general-purpose library code, as illustrated in Listing 5. It
creates a thread that enumerates prime numbers until it is interrupted
and allows the thread to exit upon interruption. The prime-seeking
loop checks for interruption in two places: once by polling the
isInterrupted() method in the header of the while loop and once when
it calls the blocking BlockingQueue.put() method.
public class PrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
PrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
public void run() {
try {
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted())
queue.put(p = p.nextProbablePrime());
} catch (InterruptedException consumed) {
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
}
I don't understand the bolded text now.
Short answer:
If you can deal with the situation, it is allowed to swallow it.
The interrupted exception occurs when the process occurring in that parallel thread was cancelled, or well, interrupted. So if you are the only one interested in that fact, and you can deal with the situation of having that thread "dead", then you can swallow it.
That is perfectly possible in real life examples. The strategy depends on each situation.
ExecutorService would be an example of the third statement.
This coordinates the execution of multiple runnables(/callables) on the same "actual" thread.
If one runnable is interrupted whilst being executed, that interruption should not affect execution of subsequent runnables.
So, ExecutorService should swallow the interruption, having dealt with it appropriately from the perspective of the interrupted runnable, in order to allow reuse of the thread for the next runnable.
Suppose we write a utility code and there is some clinet code dependent upon our code. If an InterruptedException occurs, it should not be consumed in the utility method (in a try block), it should be thrown and also as InterruptedException clears the interrupt flag, it must be set again to true by invoking interrupt method.
Its the core code which needs to take care of the decision to be taken upon occurrence of an InterruptedException [update] This core code may depend upon the interrupt flag or the InterruptedException to terminate a loop, end thread's execution or any other decision.
Moreover utility or library are the low level code which is invoked from higer level client code. Low level should ideally propogate such exception to let the higher level code manage it.
Why is Thread.stop() deprecated in Java? On their website, I see the following:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.
I don't understand what they mean by "monitors". Regardless, my question is if Thread.stop() should not be called then how should a Java thread be stopped?
You asked:
My question is if theres no way to stop a thread in Java then how to stop a thread?
The Answer: In Java there's no clean, quick or reliable way to stop a thread.
Thread termination is not so straight forward. A running thread, often called by many writers as a light-weight process, has its own stack and is the master of its own destiny (well daemons are). It may own files and sockets. It may hold locks. Abrupt Termination is not always easy: Unpredictable consequences may arise if the thread is in the middle of writing to a file and is killed before it can finish writing. Or what about the monitor locks held by the thread when it is shot in the head?
Instead, Threads rely on a cooperative mechanism called Interruption. This means that Threads could only signal other threads to stop, not force them to stop.
To stop threads in Java, we rely on a co-operative mechanism called Interruption. The concept is very simple. To stop a thread, all we can do is deliver it a signal, aka interrupt it, requesting that the thread stops itself at the next available opportunity. That’s all. There is no telling what the receiver thread might do with the signal: it may not even bother to check the signal; or even worse ignore it.
Source: https://codeahoy.com/java/How-To-Stop-Threads-Safely/
When your thread handles interrupts correctly, it should be possible to instantly terminate it with use of ExecutorService interface. According to Oracle documentation, ExecutorService.shutdownNow() method, attempts to stop all actively executing tasks without waiting for their termination. There are however no guarantees beyond best-effort attempts to stop them. Here is some sample code:
class MyThread implements Runnable{
#Override
public void run() {
for (int i = 1; i < 10000000; i++)
try {
System.out.println(i + " ThreadID: " + Thread.currentThread().getId());
if (Thread.interrupted())
throw new InterruptedException();
} catch (InterruptedException e) {
return;
}
}
}
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.submit(new MyThread());
executor.shutdownNow();
Without termination each thread should print message to console 10000000 times. executor.shutdownNow() method instantly stops all three threads.
The right way is to use a join. Instead of prematurely stopping the execution of a thread, join will wait for the thread to finish execution before moving to the next statement.
Thread exampleThread = new Thread(){
public void run(){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
//handle the exception
}
}
};
exampleThread.start();
exampleThread.join();
Here exampleThread.join() will wait until exampleThread is done executing before moving to the next statement. However, the onus of making sure that the thread does finish execution is on the programmer.
In essence there is no way to stop a thread but if you design it right you should not need to stop the thread.
The logic to stop the thread should be handled in your implementation of the thread, so that you are sure that everything goes the way you want.
For example, you could create a cancel() method that changes the state of the thread, which is checked cyclically. Like this:
class StoppableThread implements Runnable {
boolean isCancelled = false;
public void run() {
while (!isCancelled) {
System.out.println("Thread is running with all its might!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void cancel () {
isCancelled = true;
}
}
From https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html:
Most uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. To ensure prompt communication of the stop-request, the variable must be volatile (or access to the variable must be synchronized
).
Threads in java are interesting because how you implement them depends on the purpose of the program you are writing.
If you do not prioritize the efficiency of your program, the thread.join() is a method that's used to wait for a Java thread to "finish" executing. Note, it's used to wait for a Java thread, not to stop a thread, and in this case we can assume a thread finishes executing after it's done running the run() method.
The reason using the thread.stop() method is dangerous, is because we do not know how the scheduler has ordered the execution of the thread, and that uncertainty is quite frustrating, but we have to accept it. Let's say you use the thread.stop method while the thread is reading objects from main memory. That may cause a huge overhead because the scheduler is now forced to sort of prioritize stopping this thread, and ignore other threads...
So this is one of the many reason why using thread.stop should be discouraged
Say i've got the following code:
public void run(){
while (true){
function1();
...
functionN();
}
}
And i wanna exit 'gracefully' - Which means for me that once i sent a shutdown signal and currently the thread is at functionK(), The thread will 'break' the loop and exit run.
So i've tried using Thread.interrupt() like this:
public void run(){
while (true){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
But this doesn't work - The thread continutes to run endlessly even with interrupt flag on.
Just for the record:
public void run(){
while (!thread.isInterrupted()){
try {
function1();
...
functionN();
} catch (InterruptedException ex) {
/* Cleanup and exit. */
}
}
}
Stops the loop, But doesn't help me. Since each function does something that might take several minutes and there are a lot of different function so checking before each function whether interrupted flag is one might be costly (Especially since most of the times the application runs smoothly).
I wonder whether there is a special mechanism i can use for that kind of problem.
The API documentation is very clear about this:
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 join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
So you can only rely on this exception if you're waiting for object monitors. There are a couple of other exceptions thrown by certain I/O operations but if you don't use them either, there is no other option than to check the interrupted() flag.
What you can do though is to re-organise your code: if you've got N methods that are called one after the other, is it not possible to abstract them out into a loop? More often than not it is possible to find a way to refactor code to support interruption, the exact way depends on your actual scenario. My first question would be: why does a single method run for minutes? That sounds a bit fishy (though it may be justified).
Either way, interruptibility isn't something that comes for free, you have to actively design interruption points if you want your code to be more responsive to interruption than the length of the main loop.
One more thing though: checking the interrupted() flag is most definitely NOT costly. Not when you spend minutes in your main loop, and it's a lot cheaper than constructing and handling an exception. I'd go as far as to say that you'll find very few things faster than a call to Thread.isInterrupted().
Actually if you are doing CPU bound work in your methods, you have to check for Thread.interrupted() by yourself and throw InterruptedException yourself. Java won't magically do it for you, unless you park at some specifically designed spaces, such as Semaphore.wait() etc.
Your second example will keep looping after the interrupt. This is because InterruptedException doesn't actually mean that the Thread's interrupted flag is set; in fact, you don't need to check it at all.
To fix this, you can simply re-interrupt the thread (to allow callers to know that the thread was interrupted), and then break:
public void run(){
while (true) {
try {
function1();
//...
functionN();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
}
As stated in the book "Java concurrency in Practice" :"Java does not provide any mechanism for safely forcing a thread to stop what is doing", so you must implement something on your side. checking the interrupted flag and handling the InterruptedException is the best way to manage thread cancellation.
If one of you function1()...functionN() is in the middle of a database transaction or a HTTP call is up to your program to handle the cancellation; you can wait until to n seconds and save the current state or cancel the transaction and roolback, the action to perform is dictated by your application logic.
For some reason I am confused over the following:
Assume that I have Thread A that absolutely needs to execute after Thread B has completed its processing.
A way to do this would be by Thread A joining Thread B.
Trivial example:
public class MainThread {
public static void main(String[] args){
Thread b = new Thread (new SomeRunnable(args[0]));
b.start();
try {
b.join();
} catch(InteruptedException e) {
}
// Go on with processing
}
}
My question is the following: What is the proper way to handle the exception in such a case?
In various example I have seen, even in text-books, the exception is ignored.
So if Thread A needs to be sure that Thread B is completely finished before proceding, if I end up in the catch due to an exception, can it be the case that Thread B may still actually be runnable/running? So what is the best way to handle this exception?
First of all you must understand what causes this exception to be thrown. Calling stop() on a thread is currently deprecated, instead when you want to stop a thread you are interrupting it by calling thread.interrupt(). This has no impact on a thread (!), the thread must explicitly check interrupted flag once in a while and stop processing gracefully.
However if the thread sleeps, waits on a lock or on another thread (by using join() like in your example) it cannot check this flag immediately or often enough. In these cases JVM will throw an exception from blocking method (let it be join()) signalling your thread that someone just tried interrupting it. Typically you can ignore that exception (meaning - do not log it) - it's the side effect that matters. For example breaking out of the loop:
public void run() {
try {
while(!isInterrupted()) {
Thread.sleep(1000);
//...
} catch(InterruptedException e) {
//no need to log it, although it's a good idea.
}
}
It's not a problem that you didn't log that exception - but you escaped from the loop, effectively terminating the thread.
Now back to your question. When your Thread A is interrupted it means some other thread requested terminating it, probably because the whole JVM shuts down or web application is being undeployed. In this case you shouldn't be doing anything except cleanup.
Moreover it most likely means Thread B is still running. But what JVM is trying to say is: "Danger! Danger! Stop waiting for whatever you were waiting for and run!".
What is the proper way to handle the exception in such a case?
Any time you get an InterruptedException the current thread should consider itself to be interrupted. Typically, that means that the thread should clean up after itself and exit. In your case, the main thread is being interrupted by another thread and should probably interrupt the Thread a that it started in turn, and then quit.
Although it is up to you whether the interrupt should be ignored I would suggest that it is a bad practice. If you were using the interrupt as some sort of signal to the thread then I would instead set some volatile boolean flag.
In terms of best practice when catching InterruptedException, typically I do:
try {
...
} catch(InterruptedException e){
// a good practice to re-enable the interrupt flag on the thread
Thread.currentThread().interrupt();
// in your case you probably should interrupt the Thread a in turn
a.interrupt();
// quit the thread
return;
}
Since catching the InterruptedException clears the interrupt flag for the thread, it is always a good idea to re-enable the interrupt flag in the catch block.
In various example I have seen, even in text-books, the exception is ignored.
Indeed. It is very bad practice to ignore any exception but it happens all of the time. Don't give into the dark forces!
can it be the case that Thread B may still actually be runnable/running?
Thread B can certainly still be running. It is the main thread that is calling the join() that has been interrupted.