Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Killing thread after some specified time limit in Java

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?

like image 840
Traker Avatar asked Apr 28 '10 21:04

Traker


People also ask

How do you stop a thread after some time?

So, if the thread uses it to read a file, calling interrupt() on this thread blocked in the read method has no effect. However, we can explicitly check for the interrupt flag after every read in a loop. This will give a reasonable surety to stop the thread with some delay.

Which method is used to stop thread for some time in Java?

Whenever we want to stop a thread from running state by calling stop() method of Thread class in Java. This method stops the execution of a running thread and removes it from the waiting threads pool and garbage collected.

How do you kill a specific thread in Java?

Modern ways to suspend/stop a thread are by using a boolean flag and Thread. interrupt() method. Using a boolean flag: We can define a boolean variable which is used for stopping/killing threads say 'exit'. Whenever we want to stop a thread, the 'exit' variable will be set to true.

Can we kill thread in Java?

In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully. Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.


2 Answers

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.

like image 155
BalusC Avatar answered Oct 17 '22 12:10

BalusC


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); } 
like image 41
ytterrr Avatar answered Oct 17 '22 10:10

ytterrr