Reputation: 714
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?
Upvotes: 1
Views: 314
Reputation: 15018
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)
}
Upvotes: 1
Reputation: 85531
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
}
Upvotes: 3