Kill an infinite-loop thread in java - java

Is there any way I can stop a thread without using deprecated stop()?
The thread invokes some methods from a potentially badly written class which may contain infinite loops. Since I can't modify this class, I have no control over the loop condition and therefore can't exit normally using interrupt() or any other variable. Is it justified in this case to use stop()?

If you cannot use stop() and cannot fix the code, your only other option is to run the code in another process and kill the process.
In your case, the simplest option is to use Thread.stop()

The problem with the stop() method is that it can leave synchronized objects in an inconsistent state (i.e. if you stop the thread while you're halfway through a synchronized object update, then only part of the object may be updated). If your thread isn't using any synchronized methods / blocks then it's safe to stop it.
If your thread might be using a synchronized block/method, then try to cleanly shut it down before calling stop, e.g. call interrupt on it and then call stop X minutes later if the thread still hasn't stopped (operating on the assumption that the thread is calling a broken method). Just be sure that the thread leaves everything in a consistent state before calling a potentially broken method.

Related

Java - Terminate a thread

I'd like to terminate a thread in java without using the deprecated stop() method.
The run() method in my thread calls to another method which performs a task which can take a long period of time, and I want to be able to stop it before it returns.
My problem is that I don't want to handle this in the method which is called from run, so for instance I can't use a global boolean variable in order to terminate the thread cause i can't check it within the method.
Is there a way I can use the interrupt() method in order to achieve this goal ?
Short answer: you have to rewrite the long-running method so that it checks, for instance, some global boolean or the interrupted flag. As per assylias suggestion in the comments below, you could for instance do while (!isInterrupted()) { ... }.
If your long-running method is in the middle of some (well behaved) blocking call, then you will want to interrupt the thread, to make it return early from the blocking call, so that you can check the condition to see if it's time to terminate.

Thread Interrupt in java

I have the following questions, if I interrupt a thread in java, a process that is running 15 minutes, it will stop the process, stop the methods or will finish this process,and not allow others continue in line?
I have a "thread" that will call a method that will do a comparison based "access" and "postgres" after it will insert in postgres, if I want to stop the thread that called this action, she will succeed the stop the process, or wait they finish?
It will not stop the thread unless the methods executing in it are willing to terminate when they receive the "interrupt" signal. Methods that throw InterruptedException usually fall into this category. Of course, all methods in the call chain need to cooperate in one way or another.
If your code does not call "interruptable" methods or has sections that don't call them for long periods, then make them check flag Thread.isInterrupted() periodically, and terminate clean and gracefully if it ever becomes true. Same thing if you ever receive (and catch, which you should) InterruptedExceptions.
Your question can be improved, though, if your intent is more specific. I was about to explain how the "thread interrupt" protocol works, but perhaps this is not what you are looking for.
When you "interrupt" a thread, it does one of three things (which are probably the same thing behind the scenes):
If the thread is currently waiting, sleeping, or joining another thread, the interrupt will cause an InterruptedException to be thrown in the target thread.
If the thread is blocked waiting on "interruptible I/O" (that is, operations on an implementation of InterruptibleChannel), a ClosedByInterruptException will be thrown.
If it's not doing one of those things, then a flag will be set on the thread. The thread can check that flag by calling Thread.interrupted() (which will immediately reset the flag)...but if it doesn't, the next call to any_object.wait(), Thread.sleep(), or any_thread.join(), and perhaps certain other blocking methods, will throw an exception.
All these exceptions, of course, are checked exceptions...which almost invariably means that there will be an exception handler nearby (which, unless the code was designed to be interruptible, will typically just ignore the exception and try the operation again). And if the thread never waits, and never checks the interrupt flag, then interrupting it won't do much.
Also, if the thread is currently waiting on something outside the control of the JVM, the interrupt might not have any effect. On some platforms (Windows comes to mind), Java has a hard time interrupting native code.
All those caveats can be summed up as: If what you want is to kill off an unruly thread, this probably isn't the way to do it. Truth is, there isn't a decent way to kill a thread without leaving your process in a potentially wacky state. What you typically want in such cases is a separate process you can kill if it gets out of hand.
From the source:-
An interrupt is an indication to a thread that it should stop what it
is doing and do something else. It's up to the programmer to decide
exactly how a thread responds to an interrupt, but it is very common
for the thread to terminate. This is the usage emphasized in this
lesson. A thread sends an interrupt by invoking interrupt on the
Thread object for the thread to be interrupted. For the interrupt
mechanism to work correctly, the interrupted thread must support its
own interruption.

Java InterruptedException - I'm confused as to what it even means for a thread to be interrupted or why it would be

I keep getting this exception inside of a synchronized block, in which I call wait on the same object I'm synchronized on. What does it mean for a thread to be interrupted first of all?
secondly, what are normal scenarios where this would happen? any advice as to what could be going on or what I should do?
The interrupt mechanism is used to inform a thread that it should terminate itself as soon as possible. This allows the interrupted thread to exit safely without leaving any data in an inconsistent state.
What does it mean for a thread to be interrupted first of all?
It means that something has called Thread.interrupt() on the thread object. This sets the interrupted flag on the thread, and causes certain method calls to terminate with an exception.
Secondly, what are normal scenarios where this would happen?
It is typically used when a second thread wants to tell this thread to stop what it is doing. The call could be direct, or it could be done by a library method. For instance, ThreadPoolExecutor.shutdownNow() uses interrupts to (try to) terminate executing tasks.
Note that interrupting a thread does not guarantee to stop it. Indeed, barring the cases where an exception is thrown, the thread will only notice that it has been interrupted if it calls interupted() or isInterupted(). Even then, it could simply clear the flag and continue as if nothing has happened.
Any advice as to what could be going on or what I should do?
Take a look at what is "controlling" the thread that got interrupted.

Java - cancel queued calls on synchronized functions

I'm just getting started with Threads in Java so this might be a basic question, but I couldn't find the answer online.
I have two threads that can call one synchronized function. The way I understand it, if the second thread calls it while the first thread has already called it, the second thread will wait until the first thread is done before calling it. However, I don't want the second thread to call it at all.
Then the easiest way is to use an explicit lock (ReentrantLock) and call its tryLock() method.
If it returns true, then it means that no other thread has the lock, and the current thread acquired it.
If it returns false, it means that another thread holds the lock, and you should not call the method.
Remember to always call unlock() in a finally block, to make sure the lock is released even in case an exception is thrown.

Java threading/volatile

I have a thread:
class Foo extends Thread
{
boolean active = true;
public void run()
{
while(active)
{
//do stuff
}
}
public void end()
{
active = false;
}
public void hibernate()
{
synchronized(this)
{
wait();
}
}
}
If another thread calls end(), will Foo immediately see that active is now false? Specifically, because active isn't volatile, I'm not sure that it will. I initially created end() as a clever way of avoiding volatile, but now I'm unsure that it will actually do what I intend.
Additionally, if another thread calls hibernate(), which thread will go to sleep? I'm intending Foo to sleep, so if this doesn't do what I intend, an alternative suggestion would be very welcome.
If another thread calls end(), will Foo immediately see that active is now false?
No it won't. Or at least, it won't see it all of the time.
If you want run to always see the new value immediately, there has to be a "comes after" relationship between the thread assigning to the variable and the thread reading it. This can be achieved:
by declaring active volatile,
by putting synchronized blocks around the statements that read and write the variable,
by making the variable an "atomic" type; e.g. AtomicBoolean, or
by using some other appropriate concurrency class; see the java.util.concurrent.* packages.
... a clever way of avoiding volatile ...
Declaring the variable to be volatile is one way of ensuring proper synchronization. It is a fact that proper synchronization imposes a performance overhead. However, proper synchronization is essential for your application to work reliably, and it is NOT "clever" to avoid it.
(Without proper synchronization, your program will probably still work most of the time, and it might even always work on some machines. However, occasionally it won't work, and the actual behavior is likely to depend on what machine you run the program on, what the machine load is, and other things.)
Additionally, if another thread calls hibernate(), which thread will go to sleep?
The thread that makes the call will go to sleep. And it won't wake up unless some other thread does a notify or notifyAll on the same Foo object.
If you simply want the application to go to sleep and wake up a bit later, use Thread.sleep. But beware that using sleep in the wrong way can make your application slow and unresponsive.
Your suspicion is correct: because active isn't volatile, there is no guarantee that run() will ever see the change made on another thread.
Generally speaking, “clever” ways of avoiding volatile are almost always a bad idea. In fact, even volatile is something you should prefer not to resort to. Most of the time it's safer to stick to locks, monitors, or higher-level synchronization mechanisms.
For your second question, the thread that will go to sleep is the one that called hibernate(). That thread will sleep until it is interrupted, it experiences a spurious wakeup, or some other thread calls notify()/notifyAll() on the Foo instance's monitor. It is usually a mistake to call Object#wait() without surrounding it with a loop that checks the condition being waited for.
You also seem to be confused about the idea of a Foo instance “going to sleep”. A Foo instance isn't a Thread (or even a Runnable), and doesn't create its own thread, so the idea of it going to sleep doesn't make a lot of sense. What you are probably trying to achieve is putting the thread calling Foo#run() to sleep.
Regarding your first question of avoiding volatile , you should try using Thread interruption to signal a running thread to stop.
Use interrupt() instance method from another thread to interrupt running thread.
Use isInterrupted() method in your running thread to check for interruption.
while(!this.isInterrupted()){
//do your work here.
}
Not sure why you want to extend Thread class. If you implements Runnable in that case you should use interrupted in your run method to check for interruption . Please read javadocs to know about some caveats of this method.

Categories