0

I have a thread, inside its making a database call that sometimes hangs, normally timeout should be handle in the client library, but in this case the client library doesn't handle it correctly so I have to add an extra scheduled job to cancel the thread that is making db call if it takes too long to avoid back pressure.

Right now I am terminating the thread through

final Future handler = executor.submit(new MyTask());

executor2.schedule(new Runnable(){
            public void run(){
                handler.cancel(true);
            }
}, 3, TimeUnit.SECONDS);

Is there a proper way to interrupt a thread without TimeUnit.MILLISECONDS.sleep(1); ? Adding sleep seems hacky

    @Override
    public Boolean call() {
        try  {
            // Sometimes hangs
            db.call();
            // Need it to be here to call InterruptedException
            TimeUnit.MILLISECONDS.sleep(1);
            return true;
        } catch (InterruptedException e) {
            return false;
        }
    }
user10714010
  • 865
  • 2
  • 13
  • 20
  • Possible duplicate https://stackoverflow.com/questions/2758612/executorservice-that-interrupts-tasks-after-a-timeout – Sambit May 24 '19 at 17:56
  • You definitely don't need to sleep to check if a thread was interrupted. Just `return Thread.currentThread().interrupted();`. (The sleep doesn't run until the db call returns anyway, so this sleep doesn't help your db call finish earlier). – Andy Turner May 24 '19 at 18:39

2 Answers2

1

Is there a proper way to interrupt a thread without TimeUnit.MILLISECONDS.sleep(1); ? 

This doesn't interrupt a thread. It merely checks if the thread has been interrupted, either before or during the sleep, and throws an InterruptedException if it was.

If you want to interrupt a thread, use:

t.interrupt();

If you want to check if the current thread has been interrupted, use:

Thread.interrupted()

Note that this clears this interrupted state: use Thread.currentThread().isInterrupted() to check without clearing the state.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
0

As of Java 9, you can use CompletableFuture.orTimeout:

Future<?> handler = CompletableFuture.runAsync(new MyTask())
    .orTimeout(3, TimeUnit.SECONDS);
VGR
  • 40,506
  • 4
  • 48
  • 63