How can I test behavior of my application code for the case of very bad IO performance without using mock streams that sleep (because they would react to interrupts)?
For instance, I want to test a ConcurrentWrapper utility that has a pool of threads for file IO. It submits each operation to an ExecutorService with invokeAll() with timeout. I want to confirm not only that the call with ConcurrentWrapper exits before timeout, but also that it somehow made the thread of its inner ExecutorService terminate (to avoid leakage).
I need to somehow simulate slow IO in the inner thread, but in a way that will ignore interrupts (like real IO does).
A bit of clarification: No answer like "sleep and swallow InterruptedException" or "sleep, catch InterruptedException and go back to sleep" is acceptable. I want to test how my code handles interrupts and such instrumentation would defeat the purpose by handling them itself.
You can sleep in a way that will insist on sleeping through interrupts:
long start = System.currentTimeMillis();
long end = start + sleepTime;
for (long now = start; now < end; now = System.currentTimeMillis()) {
try {
Thread.sleep(end - now);
} catch (InterruptedException ignored) {
}
}
For testing with timeouts, you can actually put a maximum time to execute the test, in JUnit you can include the annotation timeout:
#Test(timeout=100)
public void method_withTimeout() {
while(true);
}
For the part of testing that the method exits, you could use the Future interface that provides a timeout for getting the results.
If i understand your question correctly, ReentrantLock might help.
final ReentrantLock lock = new ReentrantLock();
Callable<Void> c = new Callable<Void>() {
public void call() {
lock.lock();
try {
if (Thread.currentThread().isInterrupted()) {
...
}
}
finally {
lock.unlock();
}
}
}
// Submit to the pool
Future<Void> future = executorService.submit(c);
// you might want to sleep a bit to give the pool a chance
// to pull off the queue.
// Issue a cancel
future.cancel();
// Now release the lock, which should let your
// callable continue onto to the interrupted check.
lock.unlock();
Note that the "lock" method does not throw any InterruptedException (though there is a method for that called "lockInterruptibly"), and if you look at the code for that class, it's not catching and swallowing (as you've stated would not be what you want).
Related
I have this scala code, which works just fine (run() is overridden in class)
val processRunnable = new myProcessClassWithOverriddenRunFunction()
val processThread = new Thread(processRunnable)
processThread.start
What I want to do is set a timeout for processThread thread. How can I do that?
I did some research and couldn't find any parameter we can pass to new Thread() or any function in processThread to achieve that.
Found some solutions on stackoveflow which implemented a ExecutorService but unfortunately, that is not implementable in this particular problem as making another new ExecutorService for just a single processThread, everytime this function is called seems inefficient. There are some other reasons as well but my question is how can I implement that functionality on this code?
There is no way to achieve that without the thread cooperating. This is similar in nature to how to make a thread interruptible, and has to do with the fact that it is in general unsafe to stop running threads asynchronously (and a timeout is asynchronous).
Your thread needs to include the timeout capability as part of it's implementation, so that it can act on a timeout condition when it is safe for it to do so.
For example:
public class MyProcessClass {
private final long timeoutMillis = 30000;
public void run() {
long timeout = System.currentTimeMillis() + timeoutMillis;
while (System.currentTimeMillis() < timeout) {
// Process next chunk of work
}
}
}
PS. Don't be misled by the other answer based on the ExecutorService - it requires the thread to be interruptible, i.e. the same solution as shown above.
while (!Thread.interrupted()) {
// Process next chunk of work
}
In Java, you can use
CompletableFuture<Void> future = CompletableFuture.runAsync(processRunnable);
future.get(1000, TimeUnit.MILLISECONDS);
To future.get function will throw a TimeOutException when timeout (1 second in the example above) is reached and the timeout case can be handled in catch block.
Complete code will be something like this:
try {
CompletableFuture<Void> future = CompletableFuture.runAsync(processRunnable);
future.get(1000, TimeUnit.MILLISECONDS);
}
catch{
case texc : TimeoutException => println("Timeout is reached.")
case exc : Exception => println(exc.getmessage)
}
Why invoke the method Thread.currentThread.interrupt() in the catch block?
This is done to keep state.
When you catch the InterruptedException and swallow it, you essentially prevent any higher-level methods/thread groups from noticing the interrupt. Which may cause problems.
By calling Thread.currentThread().interrupt(), you set the interrupt flag of the thread, so higher-level interrupt handlers will notice it and can handle it appropriately.
Java Concurrency in Practice discusses this in more detail in Chapter 7.1.3: Responding to Interruption. Its rule is:
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.
I think this code sample makes things a bit clear.
The class which does the job :
public class InterruptedSleepingRunner implements Runnable {
#Override
public void run() {
doAPseudoHeavyWeightJob();
}
private void doAPseudoHeavyWeightJob() {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
// You are kidding me
System.out.println(i + " " + i * 2);
// Let me sleep <evil grin>
if (Thread.currentThread().isInterrupted()) {
System.out.println("Thread interrupted\n Exiting...");
break;
} else {
sleepBabySleep();
}
}
}
protected void sleepBabySleep() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The Main class:
public class InterruptedSleepingThreadMain {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new InterruptedSleepingRunner());
thread.start();
// Giving 10 seconds to finish the job.
Thread.sleep(10000);
// Let me interrupt
thread.interrupt();
}
}
Try calling interrupt without setting the status back.
Note:
http://download.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
How do I stop a thread that waits for long periods (e.g., for input)?
For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation:
Thread.currentThread().interrupt();
This ensures that the Thread will reraise the InterruptedException as soon as it is able.
I would consider it a bad practice or at least a bit risky.
Usually higher level methods do not perform blocking operations and they will never see InterruptedException there. If you mask it in every place you perform interruptible operation, you will never get it.
The only rationale for Thread.currentThread.interrupt() and not raising any other exception or signaling interrupt request in any other way (e.g. setting interrupted local variable variable in a thread's main loop) is the situation where you really can't do anything with the exception, like in the finally blocks.
See Péter Török's answer, if you want to better understand implications of the Thread.currentThread.interrupt() call.
Refer from java doc
If this thread is blocked in an invocation of the wait(), join(),
sleep(long), then its interrupt status will be cleared and it will
receive an InterruptedException.
If this thread is blocked in an I/O operation, 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.
If none of the previous conditions hold then this thread's interrupt
status will be set.
So, if you change the sleepBabySleep() method in #Ajay George Answer to I/O operation or just a sysout, you don't have to set the status back to stop the program. (BTW, they don't even throw InterruptedException)
Just like #Péter Török said => This is done to keep state. (And particular for method that will throw InterruptedException)
General question about design here. I have a few threads that need to stay running in the background, basically some database upload/failure handling tasks. The all have the following flow pattern:
public class Worker implements Runnable {
private AtomicBoolean isAlive = new AtomicBoolean(true);
....
public void run() {
while (isAlive.get()) {
// do some work here, slightly heavy
if (Thread.interrupted()) {
// checking Thread.interrupted() as the code above
// can take a while and interrupt may happen before
// it gets here.
isAlive.setBoolean(false);
break; // to exit faster
}
try { Thread.sleep(sleepTime); }
catch (InterruptedException e) {
isAlive.setBoolean(false);
break; // to exit faster
}
}
cleanUp(); // e.g. close db connections etc
}
}
Now I would like to be able to interrupt the threads so it can break out of the while loop gracefully and run the cleanUp() method.
There are many ways to do this, to list a few:
Kick the Runnables off in Threads, then use the interrupt() method:
List<Thread> threadList =...
for (int i < 0; i < threadCount; i++) {
Thread t = new Thread(new Worker());
threadList.add(t);
t.start()
}
// later
for (Thread t : threadList) { t.interrupt(); }
ThreadPoolExecutor, then use shutdownNow():
ThreadPoolExecutor executor = new ....;
executor.execute(new Worker());
// some lines else later
executor.shutdownNow(); // shutdown() doesn't interrupt?
What is the way to handle this type of workflow and why? All ideas welcome.
Over all, I personally think setting isAlive to false is the cleanest.
According to my knowledge, interrupt() is native code, which is a reason itself to stay away from.
Don't forget to set the boolean to volatile.
I think both are acceptable approaches. If you have a lot of threads, I'd go with the threadpool approach for the easier management. If you just have one (maybe two) threads, I would interrupt them individually.
As MouseEvent stated, it would be cleaner to not use the interrupt and use that isAlive variable (which seems to be pointless in your implementation). This, however, implies that you need to close or shutdown each of the instances (still a good approach)
Also, I would surround the entire method in a try-catch-finally statement where you catch the interruption and have the cleanup in the finally clause.
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.
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
}