Contractor - thread timeout

While I was studying ExecutorService , I came across a Future.get() method that takes a timeout .

Java document of this method says


Waits, if necessary, for no more than the specified time to complete the calculation, and then retrieves its result, if available.

Parameters:

latency maximum latency

unit timeout argument time unit


According to my understanding, we callable timeout on callable , we send it to ExecutorService , so my callable will interrupt after the specified time (timeout) has passed

But according to the code below, longMethod() seems to work outside of the timeout (2 seconds), and I'm really confused, realizing this. Can someone point me in the right way?

 import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Timeout implements Callable<String> { public void longMethod() { for(int i=0; i< Integer.MAX_VALUE; i++) { System.out.println("a"); } } @Override public String call() throws Exception { longMethod(); return "done"; } /** * @param args */ public static void main(String[] args) { ExecutorService service = Executors.newSingleThreadExecutor(); try { service.submit(new Timeout()).get(2, TimeUnit.SECONDS); } catch (Exception e) { e.printStackTrace(); } } } 
+3
source share
3 answers

my called will interrupt after the specified time (timeout)

Not true. The task will continue, instead you will have a zero line after the timeout.

If you want to cancel it:

  timeout.cancel(true) //Timeout timeout = new Timeout(); 

PS Since you have it right now, this interruption will have no effect. You do not check it in any way.

For example, this code takes into account interrupts:

  private static final class MyCallable implements Callable<String>{ @Override public String call() throws Exception { StringBuilder builder = new StringBuilder(); try{ for(int i=0;i<Integer.MAX_VALUE;++i){ builder.append("a"); Thread.sleep(100); } }catch(InterruptedException e){ System.out.println("Thread was interrupted"); } return builder.toString(); } } 

And then:

  ExecutorService service = Executors.newFixedThreadPool(1); MyCallable myCallable = new MyCallable(); Future<String> futureResult = service.submit(myCallable); String result = null; try{ result = futureResult.get(1000, TimeUnit.MILLISECONDS); }catch(TimeoutException e){ System.out.println("No response after one second"); futureResult.cancel(true); } service.shutdown(); 
+12
source

The timeout on get () is how long the client will wait for the future to complete. This does not affect future performance.

 Object result; int seconds = 0; while ((result = fut.get.(1, TimeUnit.SECOND)) == null) { seconds++; System.out.println("Waited " + seconds + " seconds for future"; } 
+2
source

my called will interrupt after the specified time (timeout)

The above statement is incorrect, usually Future.get blocks. Specifying a timeout allows you to use it in a non-blocking manner.

This is useful, for example, for applications with a critical time, if you need a result within 2 seconds, and getting after that means that you can not do anything about it.

0
source

Source: https://habr.com/ru/post/1499743/


All Articles