Interrupting a thread prior to calling Future.get() - java

I'm trying to write an integration test that causes an InterruptedException to be raised from the production code:
#Test
public void test() {
productionObject = new ProductionObject(
com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor());
Thread.currentThread().interrupt();
assertThat(productionObject.execute(), equalTo(defaultResponse));
}
Inside productionObject's implementation:
try {
for (Future<T> future : executorService.invokeAll(tasks))) {
results.add(future.get());
}
return results;
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // preserve interrupt flag
return defaultResponse;
}
Inside AbstractQueuedSynchronizer.acquireSharedInterruptibly() I see:
if (Thread.interrupted())
throw new InterruptedException();
So I would expect this test to pass consistently.
I've seen this fail in our build server (results are returned rather than defaultResponse). I've been unable to reproduce the failure locally, running the test in a while (true) loop, and simulating higher load by running glxgears with software rendering ;-) Can anyone spot my mistake, give me some suggestions on where to look, or suggest tools that could help me?

Strange. I read the code the same way you do. I see:
FutureTask.get() calls Sync.get(). I assume we are dealing with FutureTask here.
Sync.get() calls Sync.innerGet()
Sync.innerGet() calls acquireSharedInterruptibly(0);
Which has the code right off:
if (Thread.interrupted())
throw new InterruptedException();
I would think that this would always throw. Maybe there is some sort of race condition so the thread does not yet know that it has been interrupted? Have you tried to sleep for 100ms after you interrupt the thread?
I just ran the following test on my multi-cpu Mac and it never fails so it does not look like a race condition -- at least with my architecture and JRE version 1.6.0_41.
for (long i = 0; i < 10000000; i++) {
Thread.currentThread().interrupt();
assertTrue(Thread.interrupted());
}

Using sameThreadExecutor() in this context might actually be contra-productive since the interrupt might than occur in one of the tasks. Otherwise the code looks fine. Try using kicking off actual other threads and let one of the tasks wait long enough for your interrupt.

I've "fixed" this by interrupting the thread from within the Callable rather than from the test method itself. This makes the interruption occur closer to call to acquireSharedInterruptibly().
I can only imagine that somewhere on the code path the interrupt flag is sometimes being cleared (perhaps by JUnit or Maven surefire, which are executing test methods in parallel). I've probably only reduced the likelihood of the race condition, rather than fixing it :-/

Related

killing a java thread in test

I'm writing a sort of tutorial about programming (it will be a Java repo on github) where users can clone the repo and write their own code inside empty methods to solve algorithmic problems. After they write their code, they can launch unit tests to check if their solution is correct and if it completes execution in less than a certain time (to assure they found the most efficient solution).
So my repo will contain a lot of classes with empty methods and all the non-empty unit tests to check the code the users will write.
What I'm doing in the JUnit tests is something like that:
// Problem.solveProblem() can be a long running task
Thread runner = new Thread(() -> Problem.solveProblem(input));
runner.start();
try {
Thread.currentThread().sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
if (runner.isAlive()) {
fail("Your algorithm is taking too long.");
runner.stop();
}
Now, if a user writes a not optimized algorithm, the test fails correctly, but the runner thread will continue to run (and so will do the test thread) until it terminates, which can happen after minutes, though I call running.stop(). So I have tests that can last minutes instead of seconds like I'd like.
I know how to gracefully kill a thread in Java, but in this case I don't want the users to take care of multithreading issues (like checking/updating shared variables): I just want them to write only the code to solve the problem.
So my question is: is there a way to abruptly kill a thread in Java? If not, is there any other approach I could follow to accomplish my goal?
Thanks,
Andrea
You can use a ScheduledExecutorService with a timeout:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Future<?> future = executor.schedule(() -> Problem.solveProblem(input));
try {
future.get(500, TimeUnit.MILLISECONDS);
} catch (Exception e){
fail("Your algorithm is taking too long.");
future.cancel(true);
}
Will probably require some refinements but you get the basics.
Use Thread.currentThread().getThreadGroup() to iterate through. Thread.stop is the brute-force way, but in your case it'll probably work if you call Thread.interrupt -edit- I read this too quickly and thought you were calling sleep in your spawned threads. Rereading, I see that you are just doing this in your main thread, so as RealSkeptic commented on this post it is uncertain and probably unlikely that interrupt will solve the problem

Is this appropriate use of Thread.interrupt()?

I want a piece of code to run as long as the thread isn't interrupted. Currently what I'm doing is this:
while(!Thread.interrupted()){
// .. some code
try {
Thread.sleep(4000);
} catch(InterruptedException ex){
break;
}
// .. some more code
}
My question is: is this good practice? Is it appropriate use of interrupt?
Yes, I think this is the very purpose of interrupt(), so it seems like a legitimate usage.
Conceptually this is on the right track. There are some details that could be improved, though.
What's right about this is that the thread interruption mechanism is being used to tell the thread to do something else, and the thread can respond how it pleases at a time of its choosing. In this case, catching InterruptedException from Thread.sleep() and breaking out of the loop is an entirely reasonable thing to do. It's certainly much preferable to what is usually done, which is to ignore the exception entirely. (This is usually wrong.)
What might be an issue is that the loop condition also checks whether the thread has been interrupted. This might be a problem, depending on what some code and some more code are doing. Your system might be left in different states depending on which chunks of code have been executed when the interrupt is detected.
Unless one iteration of your loop runs for a really long time (aside from the sleep), it's usually only necessary for there to be a single interruption point in a loop. In this case, if the thread is interrupted while it's doing some code processing, an InterruptedException will be generated immediately upon the call to Thread.sleep(). So you could just change the loop condition to while (true) and have the catch-block break out of the loop. (If you do this, you should also reassert the interrupt bit; see below.)
Alternatively, if you only want to check for interrupts at the top of the loop, you could do this:
while (!Thread.interrupted()) {
// .. some code
try {
Thread.sleep(4000L);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
}
// .. some more code
}
This arranges there to be only a single exit point from the loop, which might makes the code easier to reason about.
Note the technique used here is to reassert the interrupt bit on the thread after having caught InterruptedException. The general rule about handling interrupts is that either the interrupt bit should be reasserted, or an InterruptedException should be propagated. If neither is done, then the calling code might end up blocked in a subsequent wait() call, with no knowledge that it had ever been interrupted. That's usually an error.
Good practice is to use the newer higher level APIs such as an ExecutorService instead. You shouldn't use the lower level APIs such as threads or synchronize or wait/notify.

Always call Thread.currentThread().interrupt(); when catching an InterruptedException?

This IBM developerWorks article states:
“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 […]”.
I always implemented Runnable for my threads by now. Giving a Runnable implementation like this:
public class View() implements Runnable {
#Overload
public void run(){
Thread worker = new Thread(new Worker());
worker.start();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
worker.interrupt();
// Thread.currentThread().interrupt();
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement? Doesn’t return; perform a clean enaugh exit already? What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”. What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown? Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
BTW, is it a better code design to extend Thread instead of implementing Runnable?
It resets the interrupt flag. This JavaSpecialists newsletter covers this confusing topic in more detail.
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
So if you know that your code is not going to be used by another component, then you don't need to re-interrupt. However I really wouldn't make that minor optimisation. Who knows how your code is going to be used/reused in the future (even by copy/paste) and consequently I would reset the flag for every interrupt.
Here is an example where return it is not enough:
public void doSomething1() {
while (someCondition1()) {
synchronized {
try {
this.wait();
} catch (InterruptedException e) {
return; // Should be Thread.currentThread().interrupt();
}
}
}
}
public void doSomething2() {
while (someCondition2()) {
doSomething1();
}
}
As the exception throw clears the interrupted state next time doSomething1() is executed the status is cleared and the thread does not terminates.
I prefer extending Thread because it gives you a better understanding of what the thread is doing, but it is not necessarily better code design.
As Brian stated ,it resets the interrupt flag but that doesn't say much. In your case it will do nothing and the View-Thread will keep on running.
When interrupting a Thread, the standard procedure is that the Thread should stop running. It won't do this automatically and you have to implement a way to stop it once it is interrupted.
Using the built-in functionality there are two options:
Have the main loop inside the try-block for the InterruptedException. This way, when it is interrupted you you will be thrown out of the loop and the method will exit.
The above can be bad if you have to save the state as it may corrupt the state. As an alternative, you can set the interrupted-flag (as said when it's thrown. re-interrupt it Interrupt the Thread
Either way, you have to check that the Thread is interrupted in your while-loop (with !Thread.currentThread().isInterrupted()-statement in the while-loop) or it may/will not exit. You're not fulfilling one of the first options and neither checking the flag, so your View-thread will keep on running after being interrupted.
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement?
As a point, I always do. We all copy-and-paste code and swallowing the interrupt is such a serious problem that I as a rule always do it, even if the thread is about to die.
Doesn’t return; perform a clean enough exit already?
If you are sure that it is the last return before the run() method completes and the thread exits, then yes, it not technically necessary. But see above. For posterity, return; doesn't do anything with the interrupt flag.
The question is whether your View class has been wrapped. Are you sure that when you return you are exiting the Thread. Maybe someone is delegating to it. AOP may be in place to do some sort of instrumentation.
What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”.
In general, it is important to not swallow the interrupt when your code is called by some sort of wrapping code (delegation, AOP, etc) which needs the interrupt flag. If you are swallowing it, the wrapper won't be able to use it. But in this case, there is no benefit.
What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown?
Nothing. Once the thread exits the interrupt state is worthless. And actually, it looks like the interrupt state isn't even persisted after the thread is dead.
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("caught");
}
}
});
thread.start();
thread.interrupt();
System.out.println(thread.isInterrupted());
thread.join();
System.out.println(thread.isInterrupted());
Prints:
true
caught
false
Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
I can't. There is no code outside of the thread's run() method unless someone is wrapping your runnable in other code without your knowledge.
This may happen if you are using an ExecutorService but in that case the thread's interrupt status is specifically cleared with a wt.isInterrupted() before the job is run.
So again, the reason is to do is is because it's a good pattern and that's what's important in software engineering.

Do I have to use thread.interrupted()?

I am writing a GUI for a program that takes some inputs and runs an algorithm on them. The code for the algorithm is fairly long and complex so I have just been launching a new thread from the GUI in order to perform the computations on the inputs.
//algorithmThread previously initialized
if(e.getSource() == startButton) {
if(update.updateStrings(textFields)) {
algorithmThread.start();
}
}
We want to add functionality that will allow the user to stop the computation (it runs for about half an hour on my laptop before producing a result) in the case that they have provided the wrong input files. This is how I am handling that.
else if(e.getSource() == stopButton) {
//if the user presses the stop button then intterupt the
//thread running the algorithm
algorithmThread.interrupt();
System.out.println("algorithm stopped"); //debugging code
//recreate the thread in case the user hits the start button again
algorithmThread = new Thread() {
public void run() {
runNOC();
}
};
}
The program does successfully stop the algorithm(although I think I should do some exception handling), allow the user to enter new input, and restart. My question is, under what conditions would I have to check Thread.interrupted() in the code for the algorithm? Is it necessary/best practice? Or is it acceptable to stop a thread in the manner illustrated above?
All the Thread.interrupt() method does is set an "interrupted" flag, so stopping a thread in this manner requires its cooperation. For example, the algorithm should poll the interrupt status every once in a while, for example once per iteration. You can see an example of this in the Java concurrency tutorial.
Since you are working with a GUI, you may find it easier to run the background thread using a SwingWorker. This class has many features convenient for GUI programming, like updating the GUI when the computation has finished using the done method and canceling the computation without using Thread.interrupt(). Canceling in this manner still requires cooperation from the thread, but is safer because interrupting a thread causes an InterruptedException to be thrown in some situations, such as when the thread is sleeping in Thread.sleep or waiting on a lock in Object.wait.
interrupt is not always evil following this thread:
Is Thread.interrupt() evil?
Around here, we use this method in one specific place: handling
InterruptedExceptions. That may seem a little strange but here's what
it looks like in code:
try {
// Some code that might throw an InterruptedException.
// Using sleep as an example
Thread.sleep(10000);
}
catch (InterruptedException ie) {
System.err.println("Interrupted in our long run. Stopping.");
Thread.currentThread().interrupt();
}
This does two things for us:
It avoids eating the interrupt exception. IDE auto-exception handlers
always provide you with something like ie.printStackTrace(); and a
jaunty "TODO: Something useful needs to go here!" comment.
It restores
the interrupt status without forcing a checked exception on this
method. If the method signature that you're implementing does not have
a throws InterruptedException clause, this is your other option for
propagating that interrupted status.

Java strange thread termination

I have a system with multiple threads running - my main-thread just checks if there are jobs to be done and if there are some, it calls the sub-threads (notifyAll()) who will execute it. After that, the sub-threads just wait() until there are some new tasks.
Actually, the thread-system is running reliable, but after a longer runtime (3-5h), some sub-threads just die without a warning or an error. They just exit one after another - but again only with a time-range of 2-x hours. I have used jconsole to check this phenomenon, which threads are running and how they just simply disappear.
Furthermore, the main-thread is executing every second, but the sub-threads are mainly wait()ing and are not often used at all (since there are not so many tasks in the test environment).
The only reason I can think of is, that the JVM turns off the sub-threads since they are not often used enough?
I would be very thankfull for your help!
P.S. All threads are not defined as daemons and the main-thread just works fine!
edit
Thanks for your answers, but I actually use this loop.
public void addTask (Task in_task) throws InterruptedException {
synchronized (tasks) {
while (tasks.size() == MAXIMUM_NUMBER_OF_TASKS) {
tasks.wait();
}
tasks.offer(in_task);
tasks.notifyAll();
}
}
I use this loop, so that only some speciall amount of tasks will be executed.
The documentation for Object.wait() says:
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
}
Maybe you didn't follow this advice and got a spurious wakeup or interrupt?
Instead of writing your own multi-threaded task execution solution you could use java.util.concurrent.ThreadPoolExecutor. This would probably be a good idea no matter whether you are able to fix this bug or not.
I recommend using one of the Executors for managing your tasks. There are less chances that you will lose a possible error or exception in one of you sub-threads, so it should help you debug you program. Any exception that happens in a sub-thread will be stored inside the Future object and rethrown as an ExecutionException when you call Future#get().
List<Future<Void>> taskResults = new ArrayList<Future<Void>>();
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
while(!finished){
//say you wait (blocking) for a new task here
Callable<Void> task = getNextTask();
//put the task into the pool
Future<Void> result = es.submit(task);
taskResults.add(result);
}
//3 hours later, set `finished` to true
//at the end check that no exceptions were thrown
for(Future<Void> result : taskResults){
try{
result.get();
}catch(ExecutionException e){
//there was an error
e.getCause().printStackTrace();
}catch(InterruptedException e){
//irrelevant
}
}
In general, stuff in the java.util.concurrent helps you write much more robust multi-threaded applications, without having to resort to Object#wait() and other concurrency primitives (unless you are learning, of course).
Try setting an uncaught exception handler on each thread.
There is a setUncaughtExceptionHandler() function on the Thread. Implement the UncaughtExceptionHandler interface and print the exception.
General idea, but don't do it with anonymous classes/methods:
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
e.printStackTrace();
}
});

Categories

Resources