How do I call some blocking method with a timeout in Java? - java

Is there a standard nice way to call a blocking method with a timeout in Java? I want to be able to do:
// call something.blockingMethod();
// if it hasn't come back within 2 seconds, forget it
if that makes sense.
Thanks.

You could use an Executor:
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
return something.blockingMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// handle the timeout
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
future.cancel(true); // may or may not desire this
}
If the future.get doesn't return in 5 seconds, it throws a TimeoutException. The timeout can be configured in seconds, minutes, milliseconds or any unit available as a constant in TimeUnit.
See the JavaDoc for more detail.

You could wrap the call in a FutureTask and use the timeout version of get().
See http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/FutureTask.html

See also Guava's TimeLimiter which uses an Executor behind the scenes.

It's really great that people try to implement this in so many ways. But the truth is, there is NO way.
Most developers would try to put the blocking call in a different thread and have a future or some timer. BUT there is no way in Java to stop a thread externally, let alone a few very specific cases like the Thread.sleep() and Lock.lockInterruptibly() methods that explicitly handle thread interruption.
So really you have only 3 generic options:
Put your blocking call on a new thread and if the time expires you just move on, leaving that thread hanging. In that case you should make sure the thread is set to be a Daemon thread. This way the thread will not stop your application from terminating.
Use non blocking Java APIs. So for network for example, use NIO2 and use the non blocking methods. For reading from the console use Scanner.hasNext() before blocking etc.
If your blocking call is not an IO, but your logic, then you can repeatedly check for Thread.isInterrupted() to check if it was interrupted externally, and have another thread call thread.interrupt() on the blocking thread
This course about concurrency https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY
really walks through those fundamentals if you really want to understand how it works in Java. It actually talks about those specific limitations and scenarios, and how to go about them in one of the lectures.
I personally try to program without using blocking calls as much as possible. There are toolkits like Vert.x for example that make it really easy and performant to do IO and no IO operations asynchronously and in a non blocking way.
I hope it helps

There is also an AspectJ solution for that with jcabi-aspects library.
#Timeable(limit = 30, unit = TimeUnit.MINUTES)
public Soup cookSoup() {
// Cook soup, but for no more than 30 minutes (throw and exception if it takes any longer
}
It can't get more succinct, but you have to depend on AspectJ and introduce it in your build lifecycle, of course.
There is an article explaining it further: Limit Java Method Execution Time

I'm giving you here the complete code. In place of the method I'm calling, you can use your method:
public class NewTimeout {
public String simpleMethod() {
return "simple method";
}
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Callable<Object> task = new Callable<Object>() {
public Object call() throws InterruptedException {
Thread.sleep(1100);
return new NewTimeout().simpleMethod();
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(1, TimeUnit.SECONDS);
System.out.println(result);
} catch (TimeoutException ex) {
System.out.println("Timeout............Timeout...........");
} catch (InterruptedException e) {
// handle the interrupts
} catch (ExecutionException e) {
// handle other exceptions
} finally {
executor.shutdown(); // may or may not desire this
}
}
}

Thread thread = new Thread(new Runnable() {
public void run() {
something.blockingMethod();
}
});
thread.start();
thread.join(2000);
if (thread.isAlive()) {
thread.stop();
}
Note, that stop is deprecated, better alternative is to set some volatile boolean flag, inside blockingMethod() check it and exit, like this:
import org.junit.*;
import java.util.*;
import junit.framework.TestCase;
public class ThreadTest extends TestCase {
static class Something implements Runnable {
private volatile boolean stopRequested;
private final int steps;
private final long waitPerStep;
public Something(int steps, long waitPerStep) {
this.steps = steps;
this.waitPerStep = waitPerStep;
}
#Override
public void run() {
blockingMethod();
}
public void blockingMethod() {
try {
for (int i = 0; i < steps && !stopRequested; i++) {
doALittleBit();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void doALittleBit() throws InterruptedException {
Thread.sleep(waitPerStep);
}
public void setStopRequested(boolean stopRequested) {
this.stopRequested = stopRequested;
}
}
#Test
public void test() throws InterruptedException {
final Something somethingRunnable = new Something(5, 1000);
Thread thread = new Thread(somethingRunnable);
thread.start();
thread.join(2000);
if (thread.isAlive()) {
somethingRunnable.setStopRequested(true);
thread.join(2000);
assertFalse(thread.isAlive());
} else {
fail("Exptected to be alive (5 * 1000 > 2000)");
}
}
}

You need a circuit breaker implementation like the one present in the failsafe project on GitHub.

Try this. More simple solution. Guarantees that if block didn't execute within the time limit. the process will terminate and throws an exception.
public class TimeoutBlock {
private final long timeoutMilliSeconds;
private long timeoutInteval=100;
public TimeoutBlock(long timeoutMilliSeconds){
this.timeoutMilliSeconds=timeoutMilliSeconds;
}
public void addBlock(Runnable runnable) throws Throwable{
long collectIntervals=0;
Thread timeoutWorker=new Thread(runnable);
timeoutWorker.start();
do{
if(collectIntervals>=this.timeoutMilliSeconds){
timeoutWorker.stop();
throw new Exception("<<<<<<<<<<****>>>>>>>>>>> Timeout Block Execution Time Exceeded In "+timeoutMilliSeconds+" Milli Seconds. Thread Block Terminated.");
}
collectIntervals+=timeoutInteval;
Thread.sleep(timeoutInteval);
}while(timeoutWorker.isAlive());
System.out.println("<<<<<<<<<<####>>>>>>>>>>> Timeout Block Executed Within "+collectIntervals+" Milli Seconds.");
}
/**
* #return the timeoutInteval
*/
public long getTimeoutInteval() {
return timeoutInteval;
}
/**
* #param timeoutInteval the timeoutInteval to set
*/
public void setTimeoutInteval(long timeoutInteval) {
this.timeoutInteval = timeoutInteval;
}
}
example :
try {
TimeoutBlock timeoutBlock = new TimeoutBlock(10 * 60 * 1000);//set timeout in milliseconds
Runnable block=new Runnable() {
#Override
public void run() {
//TO DO write block of code
}
};
timeoutBlock.addBlock(block);// execute the runnable block
} catch (Throwable e) {
//catch the exception here . Which is block didn't execute within the time limit
}

In special case of a blocking queue:
Generic java.util.concurrent.SynchronousQueue has a poll method with timeout parameter.

Assume blockingMethod just sleep for some millis:
public void blockingMethod(Object input) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
My solution is to use wait() and synchronized like this:
public void blockingMethod(final Object input, long millis) {
final Object lock = new Object();
new Thread(new Runnable() {
#Override
public void run() {
blockingMethod(input);
synchronized (lock) {
lock.notify();
}
}
}).start();
synchronized (lock) {
try {
// Wait for specific millis and release the lock.
// If blockingMethod is done during waiting time, it will wake
// me up and give me the lock, and I will finish directly.
// Otherwise, when the waiting time is over and the
// blockingMethod is still
// running, I will reacquire the lock and finish.
lock.wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So u can replace
something.blockingMethod(input)
to
something.blockingMethod(input, 2000)
Hope it helps.

Related

Java Concurrency in Practice Lising7.9

all,
my English is poor, but I'll try best to explain my question.
The code as follows :
public class timedRun {
private static final ScheduledExecutorService cancelExec = newScheduledThreadPool(1);
public static void timedRun(final Runnable r,
long timeout, TimeUnit unit)
throws InterruptedException {
class RethrowableTask implements Runnable {
private volatile Throwable t;
public void run() {
try {
r.run();
} catch (Throwable t) {
this.t = t;
}
}
void rethrow() {
if (t != null)
throw launderThrowable(t);
}
}
RethrowableTask task = new RethrowableTask();
final Thread taskThread = new Thread(task);
taskThread.start();
cancelExec.schedule(new Runnable() {
public void run() {
taskThread.interrupt();
}
}, timeout, unit);
taskThread.join(unit.toMillis(timeout));
task.rethrow();
}
}
There is a statement in the book : Even if the task doesn't respond to the respond, the timed run method can still return to its caller.
My question is :
If I call this method as following:
timedRun(new Runnable() {
#Override
public void run() {
while(true);
}
}, /* doesn't matter */, /* doesn't matter */);
If r does not respond to the interrupt request, the taskThread may not be interrupted in this code.(Am I right?)
So this program may not have implemented the funtionality of timed run?
Java interruption is cooperative: it relies upon the thing being interrupted checking for the interrupting and handling it appropriately.
If you have a loop like while (true);, it does not check or respond to the interruption.
You could try something like:
while (!Thread.currentThread().interrupted());
But this is a "busy wait": it will keep on checking the interrupted flag far more often than it might change.
It is a lot better just to put the thread to sleep indefinitely:
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
// Maybe reset the interrupted flag, if appropriate.
}
since this doesn't do anything until the thread is actually interrupted.

Halt or kill main method invocation loaded with reflection in Java [duplicate]

I have a method, which writes to the database. The requirement is to make sure that this method does not execute after a certain time elapses. If it returns before that, then nothing should be done.
The one basic approach that I can think of is doing something like this.
public class LimitedRuntime {
public static void writeToDb(){
// writes to the database
}
public static void main(String[] args) {
long totalExecutionTime = 8000L;
long startTime = System.currentTimeMillis();
while(System.currentTimeMillis() - startTime < totalExecutionTime )
{
writeToDb();
}
}
}
One problem with this approach is that even if the method returns before the max total execution time, even then the program halts so as to wait for the time to elapse.
How can I do this better (or maybe more correctly) ? And if we use Thread, how can we find out which Thread executes that method ?
You can do this by sending your job to an executor:
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<?> future = executor.submit(new Runnable() {
#Override
public void run() {
writeToDb(); // <-- your job
}
});
executor.shutdown(); // <-- reject all further submissions
try {
future.get(8, TimeUnit.SECONDS); // <-- wait 8 seconds to finish
} catch (InterruptedException e) { // <-- possible error cases
System.out.println("job was interrupted");
} catch (ExecutionException e) {
System.out.println("caught exception: " + e.getCause());
} catch (TimeoutException e) {
future.cancel(true); // <-- interrupt the job
System.out.println("timeout");
}
// wait all unfinished tasks for 2 sec
if(!executor.awaitTermination(2, TimeUnit.SECONDS)){
// force them to quit by interrupting
executor.shutdownNow();
}
}
There is also an AspectJ solution for that with jcabi-aspects library:
#Timeable(limit = 5, unit = TimeUnit.SECONDS)
public String writeToDb() {
// writeToDb
}
There is an article explaining it further: Limit Java Method Execution Time

ExecutorService workStealingPool and cancel method

Can you think about any reason why this code doesn't work and always outputs "finished", but the second example works without any problems. I'm using latest JDK (8u45).
public static class MyClass implements Runnable {
#Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
return;
}
System.out.println("Finished");
}
public static void main(String[] args) {
// spot the difference ->
ExecutorService executorService = Executors.newWorkStealingPool(4);
Future future = executorService.submit(new MyClass());
Thread.sleep(100);
future.cancel(true);
}
}
And the following example works flawlessly:
public static class MyClass implements Runnable {
#Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
System.out.println("Interrupted");
return;
}
System.out.println("Finished");
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future future = executorService.submit(new MyClass());
Thread.sleep(100);
future.cancel(true);
}
}
EDIT: Added return and updated sleep times and another example.
It's simpler than I thought originally. The problem is that work-stealing-pool is internally using ForkJoinPool and ForkJoinTask doesn't support cancel(true) and therefore it's not possible to cancel task after the task is started.
See javadoc documentation (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinTask.html):
mayInterruptIfRunning - this value has no effect in the default implementation
because interrupts are not used to control cancellation.
There is no way to forcibly terminate a Thread in Java. (Twenty years ago, Java 1.0 tried to provide this, and it turned out to be unworkable; the methods which attempted to do it are deprecated with no replacement.)
You, as the author of the Runnable, are responsible for properly responding to an interrupt by cleanly terminating your own run method. In your case, you should have exited your run method in the catch-block, but you didn't; you let the method's logic continue past the catch-block. So even when the thread is interrupted, the run method's last statement is always executed.

Java Multithreading doesn't seem to be correctly working

I have a class which processes something. I'm trying to run a number of instances of this class in parallel.
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping. So I'd like to know if I'm doing something wrong?
This is the structure of the class:
public class TaskRunner implements Runnable {
private boolean isRunning = false;
public void run() {
while(true) {
while (! running) {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
process();
}
}
public void go() {
isRunning = true;
}
public void stop() {
isRunning = false;
}
private void process() {
//Do some number crunching and processing here
}
}
Here's how these are being run / managed:
public class TaskManager {
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager() {
for (int i = 0; i < 10; i++) {
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
}
public void startAll() {
for (TaskRunner r : runners) {
r.go();
}
}
}
Indeed, you are not "doing it right." If you want to create a multi-threaded Java application, the place to start is with the java.util.concurrent package.
It appears from your code that you want to run ten tasks in parallel. I assume that after "number crunching and processing," you'll want to aggregate the results and do something with them in the main thread. For this, the invokeAll() method of ExecutorService works well.
First, implement Callable to do the work you show in your process() method.
final class YourTask implements Callable<YourResults> {
private final YourInput input;
YourTask(YourInput input) {
this.input = input;
}
#Override
public YourResults call()
throws Exception
{
/* Do some number crunching and processing here. */
return new YourResults(...);
}
}
Then create your tasks and run them. This would take the place of your main() method:
Collection<Callable<YourResults>> tasks = new List<>(inputs.size());
for (YourInput i : inputs)
tasks.add(new YourTask(i));
ExecutorService workers = Executors.newFixedThreadPool(10);
/* The next call blocks while the worker threads complete all tasks. */
List<Future<YourResult>> results = workers.invokeAll(tasks);
workers.shutdown();
for (Future<YourResult> f : results) {
YourResult r = f.get();
/* Do whatever it is you do with the results. */
...
}
However, I'm not sure if in TaskManager.startAll(), when I call r.go(), whether this would cause r to start running in its own thread, or within the main thread?
So my first comment is that you should make isRunning be volatile since it is being shared between threads. If the threads are not starting when it goes to true (or seem to be delayed in starting) then I suspect that's your problem. volatile provides memory synchronization between the threads so the thread that calls go() and makes a change to isRunning will be seen immediately by the thread waiting for the change.
Instead of spinning like this, I would use wait/notify:
// this synchronizes on the instance of `TaskRunner`
synchronized (this) {
// always do your wait in a while loop to protect against spurious wakeups
while (!isRunning && !Thread.currentThread().isInterrupted()) {
try {
// wait until the notify is called on this object
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
Then in the go() method you should do the following. stop() would be similar.
public void go() {
synchronized (this) {
isRunning = true;
this.notifyAll();
}
}
Notice that you should handle thread interrupts carefully. Test for isInterrupted() in the while running loop and re-interrupt a thread when InterruptedException is thrown is always a good pattern.
The total execution time that I'm getting seems to be very high, and despite my attempts at optimizing, nothing seems to be having any effect. Also, if I run a profiler on my project in Netbeans, it shows all the threads as sleeping.
So although the threads are mostly sleeping, they are still each looping 1000 times a second because of your Thread.sleep(1). If you increased the time sleeping (after making isRunning be volatile) they would loop less but the right mechanism is to use the wait/notify to signal the thread.
Awful solution, terrible. first I highly recommend you start reading some tutorial like [this]
Second, if threads should wait for a signal to go for some job, so why just don't you wait them!!!!!, something like this
import java.util.ArrayList;
public class TaskManager
{
//////////////////////
public volatile static Signal wait=new Signal();
//////////////////////
private ArrayList<TaskRunner> runners = new ArrayList<>();
public TaskManager()
{
for (int i = 0; i < 10; i++)
{
TaskRunner r = new TaskRunner();
new Thread(r).start();
runners.add(r);
}
try {
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
pauseAll();
Thread.sleep(1000);
startAll();
Thread.sleep(1000);
haltAll();System.out.println("DONE!");
}catch(Exception ex){}
}
public void startAll()
{
synchronized(wait){
wait.setRun(true);;
wait.notifyAll();
}
}
public void pauseAll(){
wait.setRun(false);
}
public void haltAll(){
for(TaskRunner tx:runners){tx.halt();}
}
public static void main(String[] args) {
new TaskManager();
}
}
class TaskRunner implements Runnable
{
private Thread thisThread;
private volatile boolean run=true;
public void run()
{
thisThread=Thread.currentThread();
while(run){
if(!TaskManager.wait.isRun()){
synchronized(TaskManager.wait)
{
if(!TaskManager.wait.isRun()){
System.out.println("Wait!...");
try
{
TaskManager.wait.wait();
}
catch (Exception e)
{
e.printStackTrace();
break;
}
}
}}
process();
}
}
private double r=Math.random();
private void process(){System.out.println(r);try {
Thread.sleep(10);
} catch (Exception e) {
// TODO: handle exception
}}
public void halt(){run=false;thisThread.interrupt();}
}
class Signal{
private boolean run=false;
public boolean isRun() {
return run;
}
public void setRun(boolean run) {
this.run = run;
}
}
in above sample, all runners works till the Signal run boolean is true, and simple TaskManager class set tit as false for every time it needs to pause the threads. and about the halt, it just set the shutdown(run) flag to false, and also interrupt the thread because of if thread is in wait state.
I hope I could prove your solution is like dream-on story, and also could explained enough about my solution.
have a good parallel application :)

Lightweight long-running method cancel pattern for Java

Is there a lightweight pattern to cancel long running method, which replaces code like this:
public void longComputations() {
... first step...
if ( cancelled ) {
rollbackWork();
return;
}
... second step...
if ( cancelled ) {
rollbackWork();
return;
}
... third step...
if ( cancelled ) {
rollbackWork();
return;
}
}
I know that I can make a Task class, subdivide steps to task objects, make a queue and just do tasks step by steps in loop with cancelation checking, but I'm just wondering is there any simple code-structure pattern for such situation.
I am not aware of such a mechanism. Since you have to track your work in order to be able to perform rollbackWork(), a well-designed object-oriented solution is your best choice anyway, if you want to further evolve this logic! Typically, such a scenario could be implemented using the command pattern, which I still find pretty lightweight:
// Task or Command
public interface Command {
void redo();
void undo();
}
A scheduler or queue could then take care of executing such task / command implementations, and of rolling them back in order.
How about this edit, not a pattern though? Exceptions are very cheap, so it should be fast.
public void caller(){
try{
longComputations();
} catch (MeaningfulRuntimeException e){
rollbackWork(e.getStep());
}
}
public void longComputations() {
... first step...
checkStatus(1);
... second step...
checkStatus(2);
... third step...
checkStatus(3);
}
public void checkStatus(int step){
if ( cancelled ) {
... we may rollback here or throw an exception ...
throw MeaningfulRuntimeException(step);
}
}
If the steps call methods which throw InterruptedException then you can use Thread.interrupt(). You will still need to maintain enough state information to do the rollback properly.
If the steps cannot be interrupted this way, you should not consider relying on the deprecated Thread.stop() mechanism since it is inherently unsafe.
It seems that either way it makes sense to do exactly what you described: encapsulate this workflow logic in a class independent of the computation steps. It should support cancellation and/or interruption and accept a bunch of tasks to be executed. Note that the tasks to be fed into the workflow should provide at least two methods: one to perform the computation and one to roll it back.
You might want to consider using the java.util.concurrent package. You need to wrap your working steps as Callables (or Runnables).
public class InterruptibleTest {
public static void main(String[] args) { try {
final ExecutorService queue = Executors.newFixedThreadPool(1);
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
queue.submit(new Callable<Void>() { #Override public Void call() { busyWait(1000); return null; } });
final AtomicBoolean cancelled = new AtomicBoolean();
new Thread() { #Override public void run() {
try { Thread.sleep(1500); } catch (InterruptedException ex) { }
queue.shutdownNow();
cancelled.set(true);
}
}.run();
if (cancelled.get()) { rollback(); }
queue.shutdown();
System.out.println("Finished");
} catch (Exception ex) { ex.printStackTrace(System.err); } }
public synchronized static void busyWait(int millis) {
System.out.println("Start");
long until = System.currentTimeMillis() + millis;
while (System.currentTimeMillis() < until) { }
System.out.println("Stopped");
}
public synchronized static void rollback() {
System.out.println("Rollback!");
}
}
Note that shutdownNow() might call interrupt() on the currently executing work thread. You will probably also need to synchronize your rollback() because shutdownNow() returns before non-interruptible code finishes execution.

Categories