I have tried to implement timeout in the code. Basically I want to start the timeout and if timeout occurs it should call a method.
Pseudocode way:
in bar function
start timeout ---> ( at background, if timeout occurs call foo() )
in foo function
cancel timeout
print something
How to call a method after timeout occurs?
EDIT: I should have ability to re-start the timeout.
There are probably a lot of different ways to achieve it...
The simplest might be just to use java.util.Timer which will allow you to schedule a TimerTask to be executed at some time in the future...
You could also take a look at ScheduledExecutorService which I believe is it's Executor equivalent.
Perhaps this might answer your question
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(5000); //It means 5 seconds
return "Ready!";
}
}
If you have question please referring to the threads
Explanation of the future :
A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready.
Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future and return null as a result of the underlying task.
Please referring to this site
Related
I have this piece of code that I have two questions.
I'm not sure why I see TimeoutException as there's no blocking anywhere.
What I'm trying to achieve with the Collector is I have a class that will go in to collect a bunch of metrics and after the CompletableFuture is completely done then I would execute Collector to release metrics. Is finally guaranteed that it will be executed last as I think .get() is supposed to be blocked until it's finished?
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.function.Supplier;
public class FutureWithCollector
{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
Collector collector = new Collector();
finalize(() -> query(collector), collector);
}
private static void finalize(Supplier<CompletableFuture<String>> submission, Collector collector) throws ExecutionException, InterruptedException
{
ExecutorService executorService = Executors.newFixedThreadPool(1);
CompletableFuture<String> s = CompletableFuture.supplyAsync(submission, executorService).thenCompose(Function.identity());
try {
String result = s.get(1000, TimeUnit.MILLISECONDS);
System.out.println(result);
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
System.out.println(collector.getI());
}
}
private static CompletableFuture<String> query(Collector collector)
{
CompletableFuture<String> future = new CompletableFuture<>();
return future.thenApply(r -> {
collector.collectStuff();
return "Hello";
});
}
}
class Collector
{
private volatile int i;
public void collectStuff()
{
i++;
}
public int getI()
{
return i;
}
}
Output
java.util.concurrent.TimeoutException
at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
at FutureWithCollector.finalize(FutureWithCollector.java:23)
at FutureWithCollector.main(FutureWithCollector.java:15)
0
It's rather trivial, just change one of your methods:
private static CompletableFuture<String> query(Collector collector) {
return CompletableFuture.supplyAsync(() -> {
collector.collectStuff();
return "hello";
});
}
You are doing:
CompletableFuture<String> future = new CompletableFuture<>();
which is documented as:
Creates a new incomplete CompletableFuture.
Essentially, no one completes this CompletableFuture, so you will always get a timeout, no matter how big it is.
You can also change your code a bit. If you want to run something, say that explicitly:
private static CompletableFuture<Void> query(Collector collector) {
return CompletableFuture.runAsync(collector::collectStuff);
}
Then please notice that collectStuff increments a volatile, but these increments are not atomic.
And you can always use join instead of get and not handle checked exceptions (granted there is no join that takes a timeout).
I'm not sure why I see TimeoutException as there's no blocking anywhere.
As Louis Wasserman noted, it comes from s.get(1000, TimeUnit.MILLISECONDS) which is a blocking call. (Sure, it is only blocking for at most 1 second. But it is still blocking.)
Is finally guaranteed that it will be executed last.
Yes ... but that's not the salient question, because ...
as I think .get() is supposed to be blocked until it's finished?
You are NOT using get(). You are using get with a timeout!
A call to get with a timeout is NOT guaranteed to block until the task corresponding to the future has finished. It actually waits until EITHER the task has finished OR the 1 second timeout expires. (Which ever happens first.)
If you want to be sure that the task has finished, don't call get with a timeout on the CompletableFuture.
You can't have it both ways1. Either you wait until the task is finished (which could take indefinitely long) or you wait with a timeout (and the task may not have finished).
1 - ... unless you have a fully operational time machine which allows you to go into the future to find out what the task's result is going to be, and then come back to the present to deliver that value.
When you write s.get(1000, TimeUnit.MILLISECONDS), the compiler warns you to handle TimeoutException. Which is maybe why you have added a basic catch block.
catch (TimeoutException e) {
e.printStackTrace();
}
In such a case, it is always helpful to see what the javadoc tells for that method,
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* #param timeout the maximum time to wait
* #param unit the time unit of the timeout argument
* #return the computed result
* #throws CancellationException if the computation was cancelled
* #throws ExecutionException if the computation threw an
* exception
* #throws InterruptedException if the current thread was interrupted
* while waiting
* #throws TimeoutException if the wait timed out
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
Now you got 2 more Exceptions to handle, Isn't your IDE or compiler complaining you to handle them as well?
Also, finally will get executed after get() either returns desired value from Future or throws Exception (Not until it comes out of the get() since it is a blocking call).
I want to submit some SwingWorkers to ExecutorService, and get Futures from them to see later if they have finished and what the results are.
However, ExecutorService's submit method will only return a Future<?> when I want a Future<Integer>.
So, questions:
Am I extending SwingWorker correctly? The first generic type is what is returned by get() on the SwingWorker, so I guessed it is also what the Future get() method will return.
Is SwingWorker the wrong thing to use? (Trying to read about this problem, I see mostly people submitting Callables to ExecutorService) If so, what would be better and what is the best way to convert it? (my actual extension of SwingWorker is more complex than this example, and updates the GUI etc). I started trying to implement Callable in a new class but I am not sure how to implement the publish/process process (no pun intended).
Some example code that reproduces the problem:
The SwingWorker extension
import javax.swing.SwingWorker;
public class Worker extends SwingWorker<Integer, Void>
{
public Worker ()
{
}
#Override
public Integer doInBackground()
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 1;
}
#Override
public void done()
{
System.out.println("done\n");
}
}
Main - the executor.submit(w) part gives a compile error:
Type mismatch: cannot convert from Future<capture#1-of ?> to Future<Integer>
And asks if I'd like to change future to be of type Future<?> or cast the executor.submit(w) part to Future<Integer>.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main
{
public static void main (String[] args)
{
ExecutorService executor = Executors.newFixedThreadPool(2);
Worker w = new Worker();
Future<Integer> future = executor.submit(w);
}
}
You may want to use this variation of submit() to make the result type explicit:
<T> Future<T> submit(Runnable task, T result)
As discussed here, submit() doesn't do anything with result. "When the task successfully completes, calling future.get() will return the result you passed in." Note that the type of result matches that of the SwingWorker result type, T.
Code:
Integer i = 42;
Future<Integer> future = executor.submit(w, i);
System.out.println(future.get());
Console:
42
done
In the larger context of your actual program, you'll want to publish() intermediate results and process() them on the EDT.
I have (say) 2 functions which does a db-hit to fetch a lot of data. Since the two functions are executed one after the other (by the same thread), the time taken is T(f(1)) + T(f(2)). How can I execute the two functions in parallel (by means of creating 2 threads) so that the total time taken is: T(max(T(f1), T(f2))
I am done writing my complete java swing application and want to optimize it for performance now. Appreciate any insight, and excuse if the question is too naive.
Thank you!
You haven't said whether you need any return values from your functions, but given the fact that they access the database it seems very likely. A pretty nice and simple solution to that is to use Executors and Futures.
A full code example is here:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FuturesExample {
public interface ReturnTypeOne {}
public interface ReturnTypeTwo {}
public void runTwo() {
ExecutorService executor = Executors.newFixedThreadPool(2);
// Dispatch two tasks.
Future<ReturnTypeOne> first = executor.submit(new Callable<ReturnTypeOne>() {
#Override
public ReturnTypeOne call() throws Exception {
// Work, work, work...
return null;
}
});
Future<ReturnTypeTwo> second = executor.submit(new Callable<ReturnTypeTwo>() {
#Override
public ReturnTypeTwo call() throws Exception {
// Work, work, work...
return null;
}
});
// Get the results.
try {
ReturnTypeOne firstValue = first.get();
ReturnTypeTwo secondValue = second.get();
// Combine the results.
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
It consists of two sections. First in which two tasks are submitted into the thread pool.
Each ExecutorService.submit() call returns immediately a future value of the task computation. Tasks are dispatched immediately at submit() call and they run in the background. Of course you can dispatch more than two tasks.
In the second section the values of futures are obtained. What happens is that the call
to Future.get() blocks the current thread until the value is computed. It does not mean
that any task is blocked, they all are running, the thread just waits until a given task completes and returns a value. Once the first value is returned, the second Future.get() call is made. In this case, it may or may not block. If the second task has already finished (possibly before the first task) the value is returned immediately. If the second task is still running, the call blocks the current thread until the value is computed.
What the above boils down to is that your main thread will only wait as long as the longest
running task. Just what you needed.
You can dispatch 2 threads like this:
new Thread(new Runnable()
{
#Override
public void run()
{
// TODO Place your "f(1)" code here...
}
}).start();
new Thread(new Runnable()
{
#Override
public void run()
{
// TODO Place your "f(2)" code here...
}
}).start();
Is there a way to kill a child thread after some specified time limit in Java?
Edit: Also this particular thread may be blocked in its worst case (Thread is used to wait for a file modification and blocks until this event occurs), so im not sure that interrupt() will be successful?
Make use of ExecutorService to execute the Callable, checkout the methods wherein you can specify the timeout. E.g.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Here Task of course implements Callable.
Some helpful changes were introduced as part of JEP 266 in CompletableFuture since Java 9. Using orTimeout method, for now, it is possible to write it like:
CompletableFuture.runAsync(thread::run)
.orTimeout(30, TimeUnit.SECONDS)
.exceptionally(throwable -> {
log.error("An error occurred", throwable);
return null;
});
In Java 8, unfortunately, you should use some extra code. Here is an example of delegation pattern usage with help of Lombok:
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.TimeoutException;
import static lombok.AccessLevel.PRIVATE;
import lombok.AllArgsConstructor;
import lombok.experimental.Delegate;
#AllArgsConstructor(access = PRIVATE)
public class TimeoutableCompletableFuture<T> extends CompletableFuture<T> {
public static TimeoutableCompletableFuture<Void> runAsync(
Runnable runnable) {
return new TimeoutableCompletableFuture<>(
CompletableFuture.runAsync(runnable));
}
#Delegate
private final CompletableFuture<T> baseFuture;
public TimeoutableCompletableFuture<T> orTimeout(Duration duration) {
final CompletableFuture<T> otherFuture = new CompletableFuture<>();
Executors.newScheduledThreadPool(
1,
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("timeoutable-%d")
.build())
.schedule(() -> {
TimeoutException ex = new TimeoutException(
"Timeout after " + duration);
return otherFuture.completeExceptionally(ex);
}, duration.toMillis(), MILLISECONDS);
return new TimeoutableCompletableFuture<>(
baseFuture.applyToEither(otherFuture, a -> a));
}
}
Of course, the code above easily could be rewritten as just a static factory method:
public static CompletableFuture<Void> runAsyncOrTimeout(
Runnable runnable, long timeout, TimeUnit unit) {
CompletableFuture<Void> other = new CompletableFuture<>();
Executors.newScheduledThreadPool(
1,
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("timeoutafter-%d")
.build())
.schedule(() -> {
TimeoutException ex = new TimeoutException(
"Timeout after " + timeout);
return other.completeExceptionally(ex);
}, timeout, unit);
return CompletableFuture.runAsync(runnable).applyToEither(other, a -> a);
}
Not directly; I think the simplest way is to join() on that thread with that time limit, and interrupt the thread if it's not done by the time the join ended.
So,
Thread t = ...
t.join(timelimit);
if (t.isAlive()) t.interrupt();
Notice I used interrupt instead of actually killing it, it's much safer. I would also recommend using executors instead of directly manipulating threads.
Why not interrupt() it after a particular time ? Your spawned thread will have to be able to handle an InterruptedException properly.
See this article (http://www.javaspecialists.eu/archive/Issue056.html) for more information on shutting down threads cleanly.
See also the Executor/Future framework, which provide useful methods for collecting results and/or terminating threads within particular time limits.
You can use AOP and a #Timeable annotation for your method from jcabi-aspects (I'm a developer):
#Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
// do something time consuming
}
When time limit is reached your thread will get interrupted() flag set to true and it's your job to handle this situation correctly and to stop execution. Normally it's done by Thread.sleep(..).
Killing a thread is generally a bad idea for reasons linked to for the API docs for Thread.
If you are dead set on killing, use a whole new process.
Otherwise the usual thing is to have the thread poll System.nanoTime, poll a (possible volatile) flag, queue a "poison pill" or something of that nature.
Brian's right, interrupting it is safer than "stopping" the thread.
What if the thread is locking on an object mid-modification, and suddenly gets stopped (which causes the lock to be released)? You get weird results.
Do not use destroy() since that does not perform any cleanup.
The most straightforward way is to use join(), like
try {
thread.join();
} catch (InterruptedException e) {//log exception...}
You could use an ExecutorService. That would make a lot of sense if you have several threads running concurrently. If you have the need to spawn new threads while other threads are running, you can combine this with a BlockingQueue.
A ThreadPoolExecutor (an ExecutorService-implementation) can take a BlockingQueue as argument, and you can simply add new threads to the queue. When you are done you simply terminate the ThreadPoolExecutor.
private BlockingQueue<Runnable> queue;
...
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, new Long(1000),
TimeUnit.MILLISECONDS, this.queue);
You can keep a count of all the threads added to the queue. When you think you are done (the queue is empty, perhaps?) simply compare this to
if (issuedThreads == pool.getCompletedTaskCount()) {
pool.shutdown();
}
If the two match, you are done. Another way to terminate the pool is to wait a second in a loop:
try {
while (!this.pool.awaitTermination(1000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {//log exception...}
First of all, I must say that I am quite new to the API java.util.concurrent, so maybe what I am doing is completely wrong.
What do I want to do?
I have a Java application that basically runs 2 separate processing (called myFirstProcess, mySecondProcess), but these processing must be run at the same time.
So, I tried to do that:
public void startMyApplication() {
ExecutorService executor = Executors.newFixedThreadPool(2);
FutureTask<Object> futureOne = new FutureTask<Object>(myFirstProcess);
FutureTask<Object> futureTwo = new FutureTask<Object>(mySecondProcess);
executor.execute(futureOne);
executor.execute(futureTwo);
while (!(futureOne.isDone() && futureTwo.isDone())) {
try {
// I wait until both processes are finished.
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
logger.info("Processing finished");
executor.shutdown();
// Do some processing on results
...
}
myFirstProcess and mySecondProcess are classes that implements Callable<Object>, and where all their processing is made in the call() method.
It is working quite well but I am not sure that it is the correct way to do that.
Is a good way to do what I want? If not, can you give me some hints to enhance my code (and still keep it as simple as possible).
You'd be better off using the get() method.
futureOne.get();
futureTwo.get();
Both of which wait for notification from the thread that it finished processing, this saves you the busy-wait-with-timer you are now using which is not efficient nor elegant.
As a bonus, you have the API get(long timeout, TimeUnit unit) which allows you to define a maximum time for the thread to sleep and wait for a response, and otherwise continues running.
See the Java API for more info.
The uses of FutureTask above are tolerable, but definitely not idiomatic. You're actually wrapping an extra FutureTask around the one you submitted to the ExecutorService. Your FutureTask is treated as a Runnable by the ExecutorService. Internally, it wraps your FutureTask-as-Runnable in a new FutureTask and returns it to you as a Future<?>.
Instead, you should submit your Callable<Object> instances to a CompletionService. You drop two Callables in via submit(Callable<V>), then turn around and call CompletionService#take() twice (once for each submitted Callable). Those calls will block until one and then the other submitted tasks are complete.
Given that you already have an Executor in hand, construct a new ExecutorCompletionService around it and drop your tasks in there. Don't spin and sleep waiting; CompletionService#take() will block until either one of your tasks are complete (either finished running or canceled) or the thread waiting on take() is interrupted.
Yuval's solution is fine. As an alternative you can also do this:
ExecutorService executor = Executors.newFixedThreadPool();
FutureTask<Object> futureOne = new FutureTask<Object>(myFirstProcess);
FutureTask<Object> futureTwo = new FutureTask<Object>(mySecondProcess);
executor.execute(futureOne);
executor.execute(futureTwo);
executor.shutdown();
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
// interrupted
}
What is the advantage of this approach? There's not a lot of difference really except that this way you stop the executor accepting any more tasks (you can do that the other way too). I tend to prefer this idiom to that one though.
Also, if either get() throws an exception you may end up in a part of your code that assumes both tasks are done, which might be bad.
You can use invokeall(Colelction....) method
package concurrent.threadPool;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class InvokeAll {
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(5);
List<Future<java.lang.String>> futureList = service.invokeAll(Arrays.asList(new Task1<String>(),new Task2<String>()));
System.out.println(futureList.get(1).get());
System.out.println(futureList.get(0).get());
}
private static class Task1<String> implements Callable<String>{
#Override
public String call() throws Exception {
Thread.sleep(1000 * 10);
return (String) "1000 * 5";
}
}
private static class Task2<String> implements Callable<String>{
#Override
public String call() throws Exception {
Thread.sleep(1000 * 2);
int i=3;
if(i==3)
throw new RuntimeException("Its Wrong");
return (String) "1000 * 2";
}
}
}
You may want to use a CyclicBarrier if you are interested in starting the threads at the same time, or waiting for them to finish and then do some further processing.
See the javadoc for more information.
If your futureTasks are more then 2, please consider [ListenableFuture][1].
When several operations should begin as soon as another operation
starts -- "fan-out" -- ListenableFuture just works: it triggers all of
the requested callbacks. With slightly more work, we can "fan-in," or
trigger a ListenableFuture to get computed as soon as several other
futures have all finished.