Safe stop thread - java

I have some class:
#Component
public MyClass {
private volatile boolean stopped = false;
public void verification() throws Exception {
Thread kpiAllThread = getKPIAllThread();
try {
for (int i = 0; i < poolSize; i++) {
execDispatcher.put(processExecutor.submit(getCheckValuesInKPIConsumerTask(workingQueue)));
}
kpiAllThread.start();
} finally {
waitFinished();
}
}
public void setStop(bolean stopped) {
this.stopped = stopped;
}
private Thread getKPIAllThread() {
return new Thread(() -> {
try {
LOG.debug("KPIAllThread started!");
dao.getKpiAll(workingQueue);
for (int i = 0; i < poolSize; i++) {
workingQueue.put(() -> true);
}
} catch (Exception ex) {
LOG.error("KPIAllThread exception: ", ex);
} finally {
LOG.error("KPIAllThread finished!");
}
});
}
}
This class starts the producer thread getKPIAllThread. He get data from db and put in BlockingQueue.
Method getKpiAll like this:
public void getKpiAll(final BlockingQueue<KeyPropertyIndex> kpiData) throws Exception {
LOG.debug("Starting getKpiAll");
try (final Connection con = dataSource.getConnection();
final Statement stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)) {
stmt.setFetchSize(Integer.MIN_VALUE);
try (final ResultSet rs = stmt.executeQuery(sqlGetAllkpi)) {
while (rs.next()) {
kpiData.put(new KeyPropertyIndexData(rs.getLong(1), rs.getString(2)));
}
}
LOG.debug("Finished get getKpiAll");
} catch (Exception ex) {
throw ex;
}
}
There is also a variable stopped that can be set from outside to true. How can I safely stop my thread while doing so? So that all connections to the database are closed and the thread is successfully completed?

The cleanest and safest rule for stopping a thread is that the code running in thread should periodically check a condition (say, boolean shouldExit()). When the code detects that this condition is true, it should stop doing what is doing and terminate.
The code running in thread should check this condition fairly often so that it can react reasonably fast. As a rule of thumb, the thread should exit less than one second after you set this condition. The check would typically look something like if (shouldExit()) break somewhere in your for-loop that iterates over pool size. However, dao.getKpiAll(workingQueue) looks potentially long, so you might place more checks inside getKpiAll.
When you have this checking in place, you must ensure that your code will exit cleanly every time the condition becomes true. For example, you can use finally blocks to close any connections etc. If this happens during getKpiAll, there is no sense to even continue with for loop to process items and so on.
Sometimes, this can get more tricky - i.e. when the thread is waiting on a network operation, you might need to close the network socket or something like that to interrupt it. In any case, avoid using Thread.stop() or Thread.interrupt() - see documentation why they are problematic.
If you do things like this, you can set the condition from outside the thread at any time to request the thread to terminate. You can make something like void requestExit() and set a boolean variable there. After calling requestExit(), you call Thread.join() with a suitable timeout to wait for the thread to do its business, check the condition and exit. Again, as a rule of thumb, make the timeout 3-10 times as long as the longest reaction time of your thread.
It looks that you already have setStopped(boolean stopped) for that purpose, but you're not checking it. First, I would remove parameter stopped because it doesn't make sense to pass false to it. Second, you need to add checks as described above. You might want to make this variable visible to dao - just remember that it's much better to expose it as a synchronized boolean method than as a boolean field.

Related

Is it right for a thread to throw an InterruptedException for itself?

This is what I'm doing:
Stopwatch stopWatchToCheckTimeout;
void checkShutDown() throws InterruptedException {
if (stopWatchToCheckTimeout.elapsed() >= MAX_GRACEFUL_TIMEOUT_DURATION) {
throw new InterruptedException("Time to shut down now!");
}
}
public Void mainFancyMethod() {
try {
while(true) {
checkShutDown();
// do fancy work
}
} catch (InterruptedException ex) {
log.debug("Shutting down gracefully");
}
return null;
}
From the java/lang/InterruptedException documentation its not clear to me if by standards it should be another thread that should interrupt or if its okay for a thread to throw this exception for itself?
Whats the best exception to throw for this use-case?
It seems like you are using exceptions in place of control flow. Is there any reason you couldn't just have checkShutDown return a boolean?
boolean timedOut() {
return (stopWatchToCheckTimeout.elapsed() >= MAX_GRACEFUL_TIMEOUT_DURATION)
}
It is correct for a thread to throw an interrupted exception, and in fact threads are usually the sources of InterruptedException.
In your case, I don't think it's appropriate because it has nothing to do with interruption, which is an established thread state. You just want to exit the execution, which could be done in more graceful and performant ways.
TimeLimitExceededException: https://docs.oracle.com/javase/7/docs/api/javax/naming/TimeLimitExceededException.html
From the Docs: "This exception is thrown when a method does not terminate within the specified time limit. This can happen, for example, if the user specifies that the method should take no longer than 10 seconds, and the method fails to complete with 10 seconds. "
This sounds like just what you are after, or?
In the example you posted, you should not throw an InterruptedException.
The Javadoc for InterruptedException states: Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Being interrupted is a result of Thread.interrupt() being called on your running thread, which is not what's happening in the code you posted.
If you do still want to use an exception to break out of your loop, you should use some other exception type. However, an alternative would be to make your check method return true/false, and use that for the condition of your while loop. So instead of this:
try {
while(true) {
checkShutDown();
// do fancy work
}
} catch (InterruptedException ex) {
log.debug("Shutting down gracefully");
}
do something like this:
while (checkIfSafeToContinue()) {
// do fancy work
}

wait() - notify() mechanism in java malfunctioning in a strange way [duplicate]

This question already has answers here:
Why should wait() always be called inside a loop
(11 answers)
Closed 7 years ago.
I've tried reading some answers to similar questions here (I always do that) but did not find (or did not understand?) the answer to this particular issue.
I am implementing a fairly simple consumer-producer class, which receives elements to a list from a different thread and consumes them repeatedly. The class has the following code:
public class ProduceConsume implements Runnable
{
LinkedList<Integer> _list = new LinkedList<Integer>();
public synchronized void produce(Integer i)
{
_list.add(i);
notify();
}
public void run()
{
while(true)
{
Integer i = consume();
// Do something with the integer...
}
}
private synchronized Integer consume()
{
if(_list.size() == 0)
{
try
{
wait();
}
catch(InterruptedException e){}
return _list.poll();
}
}
}
The problem is - it usually works fine, but sometimes, the execution gets to
return _list.poll();
with the list still empty. I can't wrap my head around it - am I doing something terribly wrong? Shouldn't the runnable thread, which repeatedly tries to poll detect a zero length list, wait, and be awakened only after the producer method is done, hence making the list non-empty?
Nothing else "touches" the class from the outside, except for calls to produce. No other threads are synchronized on the runnable class.
By the way, for several reasons, I wish to use my own variant and not classes such as CopyOnWriteArrayList, etc.
Thanks! Any help would be greatly appreciated.
P.S - I have not used the wait-notify many times, but when I did, in the past, it worked. So if I apologize if I made some huge stupid error!
As the Javadoc for Object.wait states
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
Additionally, you shouldn't ignore an exception like InterruptedException. This will look like a spurious wake up and as you say produces an error.
private synchronized Integer consume() {
try {
while (_list.isEmpty())
wait();
return _list.poll();
} catch(InterruptedException e) {
throw new IllegalStateException("Interrupted");
}
}
Since wait releases the lock you can't reason based on conditions tested before it started waiting, assuming the condition must have changed once wait is exited is not valid. You need to call wait in a loop, so that once the thread ceases waiting and takes the lock again, it checks that the condition it's waiting for has the expected value:
private synchronized Integer consume()
{
try {
while (_list.size() == 0) {
wait();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return _list.poll();
}
From the Oracle tutorial:
Note: Always invoke wait inside a loop that tests for the condition being waited for.
Also it's not safe to assume that just because wait returned that something sent a notification. wait can return even if there is no notification (the spurious wakeup).
It's hard to say what caused what you're seeing without a complete working example.
The linked Oracle tutorial page has a Producer Consumer example you might want to look at.

How to wake up all threads waiting on same condition?

I have a following scenario. Several threads are waiting on the same condition. And when are notified, all should stop waiting, change flag and return object:
public Object getObject(){
lock.lock();
try {
while (check)){
condition.await();
}
return returnObjectAndSetCheckToFalse();
} finally {
lock.unlock();
}
}
however this code does not work, since faster thread could change check flag to false, and second slower thread will block again.
It is possible to have a logic that both waiting threads will be awaken, they both will set check flag to false, and return object?
Or maybe it is contradictory?
The easiest way would be to change wait to if statement, however this would be vulnerable to spurious wakeup.
You could use CountDownLatch or a CyclicBarrier.
Using a Future is also a possibility, a FutureTask to be more specific. It has a conveniance method get() which can be used to block code execution until the Future has completed its job, thus fulfilling your requirements.
You could also implement your own Barrier which would do wait() in a loop until a certain condition has been met. Fulfilling that condition would trigger notifyAll(), loop would finish and all threads could continue. But that would be reinventing the wheel.
As I understand you need to return from the method body in all threads if your condition.await() returns.
This ugly solution should help although I think there's a better way to solve this:
public Object getObject() {
lock.lock();
try {
int localstate = this.state;
while (check && localstate == this.state)) {
condition.await(); // all threads that are waiting here have the same state
}
if (!check) {
this.state++; // first thread will change state thus making other threads ignore the 'check' value
}
return returnObjectAndSetCheckToFalse();
} finally {
lock.unlock();
}
}
What I think is you're trying to achieve, done using Futures:
ExecutorService executor = Executors.newCachedThreadPool();
// producer
final Future<String> producer = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
Thread.sleep(5000);
return "done";
}
});
// consumers
for (int i = 0; i < 3; i++) {
final int _i = i;
executor.submit(new Runnable() {
#Override
public void run() {
System.out.println("Consumer "+_i+" starts.");
try {
String value = producer.get();
System.out.println("Consumer "+_i+" ends: "+value);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
If you run this, you should see all the consumer threads printing out their starting message, then a pause, then the consumer threads print out they're done. Obviously you'd have to change whatever is producing the value of getObject() into a Callable but I'd bet good money this will simplify the code since now it'll be structured procedurally instead of storing the result of a computation in a shared variable. I'm also more confident it's thread safe than of any code using manual locking.
One way of doing it is using wait() instead of condition.await(). Then use notifyAll() to wake up the threads.
Ideally, you would continue using the condition object that causes the thread to sleep and invoke the method signalAll() to wake up all the threads.
In you code I would just add:
public Object getObject(){
lock.lock();
try {
while (check)){
condition.await();
}
condition.signalAll();
return returnObjectAndSetCheckToFalse();
} finally {
lock.unlock();
}
}
I would even look at the possibility of using the condition.signalAll() inside the returnObjectAndSetCheckToFalse() method instead of before the return statement.
Indeed it it is contradictory. What you want to achieve is problematic. You want threads waiting on the condition should get result and continue, but a thread that invokes getObject just after notification would not. At least, it is unfair. Whether that thread manages to call getObject before notification or not, is pure random thing. You should decrease indeterminism, not to increase it.

Stopping thread Immediately

I want to stop a running thread immediately. Here is my code:
Class A :
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
Class B:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
My problem is that i need to be able to stop the thread in Class B even before the thread is finished. I've tried interrupt() method, but that doesn't stop my thread. I've also heard about using shared variable as a signal to stop my thread, but I think with long recursive and for-loop in my process, shared-variable will not be effective.
Any idea ?
Thanks in advance.
Thread.interrupt will not stop your thread (unless it is in the sleep, in which case the InterruptedException will be thrown). Interrupting basically sends a message to the thread indicating it has been interrupted but it doesn't cause a thread to stop immediately.
When you have long looping operations, using a flag to check if the thread has been cancelled is a standard approach. Your methodA can be modified to add that flag, so something like:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
Then a cancel method can be added to set that flag
public void cancel() {
cancelled = true;
}
Then if someone calls runEverything on B, B can then just call cancel on A (you will have to extract the A variable so B has a reference to it even after runEverything is called.
I think you should persevere with using Thread.interrupt(). But what you need to do to make it work is to change the methodA code to do something like this:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
This is equivalent declaring and using your own "kill switch" variable, except that:
many synchronization APIs, and some I/O APIs pay attention to the interrupted state, and
a well-behaved 3rd-party library will pay attention to the interrupted state.
Now it is true that a lot of code out there mishandles InterruptedException; e.g. by squashing it. (The correct way to deal with an InterruptedException is to either to allow it to propagate, or call Thread.interrupt() to set the flag again.) However, the flip side is that that same code would not be aware of your kill switch. So you've got a problem either way.
You can check the status of the run flag as part of the looping or recursion. If there's a kill signal (i.e. run flag is set false), just return (after whatever cleanup you need to do).
There are some other possible approaches:
1) Don't stop it - signal it to stop with the Interrupted flag, set its priority to lowest possible and 'orphan' the thread and any data objects it is working on. If you need the operation that is performed by this thread again, make another one.
2) Null out, corrupt, rename, close or otherwise destroy the data it is working on to force the thread to segfault/AV or except in some other way. The thread can catch the throw and check the Interrupted flag.
No guarantees, sold as seen...
From main thread letsvsay someTask() is called and t1.interrput is being called..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o/P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
Only t1.interuuption will not be enough .this need check the status of Thread.interrupted() in child thread.

How can I wrap a method so that I can kill its execution if it exceeds a specified timeout?

I have a method that I would like to call. However, I'm looking for a clean, simple way to kill it or force it to return if it is taking too long to execute.
I'm using Java.
to illustrate:
logger.info("sequentially executing all batches...");
for (TestExecutor executor : builder.getExecutors()) {
logger.info("executing batch...");
executor.execute();
}
I figure the TestExecutor class should implement Callable and continue in that direction.
But all i want to be able to do is stop executor.execute() if it's taking too long.
Suggestions...?
EDIT
Many of the suggestions received assume that the method being executed that takes a long time contains some kind of loop and that a variable could periodically be checked.
However, this is not the case. So something that won't necessarily be clean and that will just stop the execution whereever it is is acceptable.
You should take a look at these classes :
FutureTask, Callable, Executors
Here is an example :
public class TimeoutExample {
public static Object myMethod() {
// does your thing and taking a long time to execute
return someResult;
}
public static void main(final String[] args) {
Callable<Object> callable = new Callable<Object>() {
public Object call() throws Exception {
return myMethod();
}
};
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Object> task = executorService.submit(callable);
try {
// ok, wait for 30 seconds max
Object result = task.get(30, TimeUnit.SECONDS);
System.out.println("Finished with result: " + result);
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (TimeoutException e) {
System.out.println("timeout...");
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
Java's interruption mechanism is intended for this kind of scenario. If the method that you wish to abort is executing a loop, just have it check the thread's interrupted status on every iteration. If it's interrupted, throw an InterruptedException.
Then, when you want to abort, you just have to invoke interrupt on the appropriate thread.
Alternatively, you can use the approach Sun suggest as an alternative to the deprecated stop method. This doesn't involve throwing any exceptions, the method would just return normally.
I'm assuming the use of multiple threads in the following statements.
I've done some reading in this area and most authors say that it's a bad idea to kill another thread.
If the function that you want to kill can be designed to periodically check a variable or synchronization primitive, and then terminate cleanly if that variable or synchronization primitive is set, that would be pretty clean. Then some sort of monitor thread can sleep for a number of milliseconds and then set the variable or synchronization primitive.
Really, you can't... The only way to do it is to either use thread.stop, agree on a 'cooperative' method (e.g. occassionally check for Thread.isInterrupted or call a method which throws an InterruptedException, e.g. Thread.sleep()), or somehow invoke the method in another JVM entirely.
For certain kinds of tests, calling stop() is okay, but it will probably damage the state of your test suite, so you'll have to relaunch the JVM after each call to stop() if you want to avoid interaction effects.
For a good description of how to implement the cooperative approach, check out Sun's FAQ on the deprecated Thread methods.
For an example of this approach in real life, Eclipse RCP's Job API's 'IProgressMonitor' object allows some management service to signal sub-processes (via the 'cancel' method) that they should stop. Of course, that relies on the methods to actually check the isCancelled method regularly, which they often fail to do.
A hybrid approach might be to ask the thread nicely with interrupt, then insist a couple of seconds later with stop. Again, you shouldn't use stop in production code, but it might be fine in this case, esp. if you exit the JVM soon after.
To test this approach, I wrote a simple harness, which takes a runnable and tries to execute it. Feel free to comment/edit.
public void testStop(Runnable r) {
Thread t = new Thread(r);
t.start();
try {
t.join(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!t.isAlive()) {
System.err.println("Finished on time.");
return;
}
try {
t.interrupt();
t.join(2000);
if (!t.isAlive()) {
System.err.println("cooperative stop");
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.err.println("non-cooperative stop");
StackTraceElement[] trace = Thread.getAllStackTraces().get(t);
if (null != trace) {
Throwable temp = new Throwable();
temp.setStackTrace(trace);
temp.printStackTrace();
}
t.stop();
System.err.println("stopped non-cooperative thread");
}
To test it, I wrote two competing infinite loops, one cooperative, and one that never checks its thread's interrupted bit.
public void cooperative() {
try {
for (;;) {
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.err.println("cooperative() interrupted");
} finally {
System.err.println("cooperative() finally");
}
}
public void noncooperative() {
try {
for (;;) {
Thread.yield();
}
} finally {
System.err.println("noncooperative() finally");
}
}
Finally, I wrote the tests (JUnit 4) to exercise them:
#Test
public void testStopCooperative() {
testStop(new Runnable() {
#Override
public void run() {
cooperative();
}
});
}
#Test
public void testStopNoncooperative() {
testStop(new Runnable() {
#Override
public void run() {
noncooperative();
}
});
}
I had never used Thread.stop() before, so I was unaware of its operation. It works by throwing a ThreadDeath object from whereever the target thread is currently running. This extends Error. So, while it doesn't always work cleanly, it will usually leave simple programs with a fairly reasonable program state. For example, any finally blocks are called. If you wanted to be a real jerk, you could catch ThreadDeath (or Error), and keep running, anyway!
If nothing else, this really makes me wish more code followed the IProgressMonitor approach - adding another parameter to methods that might take a while, and encouraging the implementor of the method to occasionally poll the Monitor object to see if the user wants the system to give up. I'll try to follow this pattern in the future, especially methods that might be interactive. Of course, you don't necessarily know in advance which methods will be used this way, but that is what Profilers are for, I guess.
As for the 'start another JVM entirely' method, that will take more work. I don't know if anyone has written a delegating class loader, or if one is included in the JVM, but that would be required for this approach.
Nobody answered it directly, so here's the closest thing i can give you in a short amount of psuedo code:
wrap the method in a runnable/callable. The method itself is going to have to check for interrupted status if you want it to stop (for example, if this method is a loop, inside the loop check for Thread.currentThread().isInterrupted and if so, stop the loop (don't check on every iteration though, or you'll just slow stuff down.
in the wrapping method, use thread.join(timeout) to wait the time you want to let the method run. or, inside a loop there, call join repeatedly with a smaller timeout if you need to do other things while waiting. if the method doesn't finish, after joining, use the above recommendations for aborting fast/clean.
so code wise, old code:
void myMethod()
{
methodTakingAllTheTime();
}
new code:
void myMethod()
{
Thread t = new Thread(new Runnable()
{
public void run()
{
methodTakingAllTheTime(); // modify the internals of this method to check for interruption
}
});
t.join(5000); // 5 seconds
t.interrupt();
}
but again, for this to work well, you'll still have to modify methodTakingAllTheTime or that thread will just continue to run after you've called interrupt.
The correct answer is, I believe, to create a Runnable to execute the sub-program, and run this in a separate Thread. THe Runnable may be a FutureTask, which you can run with a timeout ("get" method). If it times out, you'll get a TimeoutException, in which I suggest you
call thread.interrupt() to attempt to end it in a semi-cooperative manner (many library calls seem to be sensitive to this, so it will probably work)
wait a little (Thread.sleep(300))
and then, if the thread is still active (thread.isActive()), call thread.stop(). This is a deprecated method, but apparently the only game in town short of running a separate process with all that this entails.
In my application, where I run untrusted, uncooperative code written by my beginner students, I do the above, ensuring that the killed thread never has (write) access to any objects that survive its death. This includes the object that houses the called method, which is discarded if a timeout occurs. (I tell my students to avoid timeouts, because their agent will be disqualified.) I am unsure about memory leaks...
I distinguish between long runtimes (method terminates) and hard timeouts - the hard timeouts are longer and meant to catch the case when code does not terminate at all, as opposed to being slow.
From my research, Java does not seem to have a non-deprecated provision for running non-cooperative code, which, in a way, is a gaping hole in the security model. Either I can run foreign code and control the permissions it has (SecurityManager), or I cannot run foreign code, because it might end up taking up a whole CPU with no non-deprecated means to stop it.
double x = 2.0;
while(true) {x = x*x}; // do not terminate
System.out.print(x); // prevent optimization
I can think of a not so great way to do this. If you can detect when it is taking too much time, you can have the method check for a boolean in every step. Have the program change the value of the boolean tooMuchTime to true if it is taking too much time (I can't help with this). Then use something like this:
Method(){
//task1
if (tooMuchTime == true) return;
//task2
if (tooMuchTime == true) return;
//task3
if (tooMuchTime == true) return;
//task4
if (tooMuchTime == true) return;
//task5
if (tooMuchTime == true) return;
//final task
}

Categories