Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple timeout in java

Can anyone guide me on how I can use a simple timeout in java? Basically in my project I'm executing a statement br.readLine(), which is reading a response from a modem. But sometimes the modem isn't responding. For that purpose I want to add a timeout. I'm looking for a code like:

try {     String s= br.readLine(); } catch(TimeoutException e) {     System.out.println("Time out has occurred"); } 
like image 871
Yuvraj Avatar asked Oct 18 '13 18:10

Yuvraj


People also ask

How do you write a timeout in java?

final Duration timeout = Duration. ofSeconds(30); ExecutorService executor = Executors. newSingleThreadExecutor(); final Future<String> handler = executor. submit(new Callable() { @Override public String call() throws Exception { return requestDataFromModem(); } }); try { handler.

How do I stop a java execution?

To stop executing java code just use this command: System. exit(1); After this command java stops immediately!

What is timeout exception in java?

Class TimeoutExceptionException thrown when a blocking operation times out. Blocking operations for which a timeout is specified need a means to indicate that the timeout has occurred.


2 Answers

What you are looking for can be found here. It may exist a more elegant way to accomplish that, but one possible approach is

Option 1 (preferred):

final Duration timeout = Duration.ofSeconds(30); ExecutorService executor = Executors.newSingleThreadExecutor();  final Future<String> handler = executor.submit(new Callable() {     @Override     public String call() throws Exception {         return requestDataFromModem();     } });  try {     handler.get(timeout.toMillis(), TimeUnit.MILLISECONDS); } catch (TimeoutException e) {     handler.cancel(true); }  executor.shutdownNow(); 

Option 2:

final Duration timeout = Duration.ofSeconds(30); ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);  final Future<String> handler = executor.submit(new Callable() {     @Override     public String call() throws Exception {         return requestDataFromModem();     } });  executor.schedule(new Runnable() {     @Override     public void run(){         handler.cancel(true);     }       }, timeout.toMillis(), TimeUnit.MILLISECONDS);  executor.shutdownNow(); 

Those are only a draft so that you can get the main idea.

like image 64
Trein Avatar answered Oct 09 '22 01:10

Trein


Nowadays you can use

try {     String s = CompletableFuture.supplyAsync(() -> br.readLine())                                 .get(1, TimeUnit.SECONDS); } catch (TimeoutException e) {     System.out.println("Time out has occurred"); } catch (InterruptedException | ExecutionException e) {     // Handle } 

EDIT: poseidon correctly points out that in the event of a timeout, the above approach does not interrupt the underlying Thread that is processing the Future's task. Without an interrupt, the underlying Thread will continue to process the Future's task to completion, with no way of knowing that the result is no longer wanted. With an interrupt, the underlying Thread can at least see (if it checks) that it has been interrupted, allowing it to gracefully conclude processing and exit.

For methods in the JDK that do blocking IO, by convention they are implemented such that they check the calling Thread's interrupt status (and throw an InterruptedException if it is true). So, interrupting a Thread can allow it to quickly exit even out of potentially-infinite wait situations, like reading from an input source.



Without further exposition, if we want to interrupt the underlying Thread on timeout, we can adjust:

Future<String> future = CompletableFuture.supplyAsync(() -> br.readLine()); try {     String s = future.get(1, TimeUnit.SECONDS); } catch (TimeoutException e) {     System.out.println("Time out has occurred");
         future.cancel(true); } catch (InterruptedException | ExecutionException e) {     // Handle } 
like image 43
Daniel Avery Avatar answered Oct 09 '22 02:10

Daniel Avery