7

How to go about implementing a "fire and forget" behavior with java.util.concurrency? I tried:

ExecutorService executor = Executors.newSingleThreadExecutor();

public void push(Callable<Boolean> task) {
    Future<Boolean> future = executor.submit(task);
    future.get(timeout, timeoutUnit);
}

but the get() is blocking until completion. The push() caller is not interested in the result of the task.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
Philippe Blayo
  • 10,610
  • 14
  • 48
  • 65

2 Answers2

15

Don't call get(). submit() is enough to start the Callable in a Thread. You can pass around the Future and call its get() when you are ready to get the result (if ever).

The Javadoc states

Submits a value-returning task for execution and returns a Future representing the pending results of the task. The Future's get method will return the task's result upon successful completion.

If you would like to immediately block waiting for a task, you can use constructions of the form result = exec.submit(aCallable).get();

So just don't call get().

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • You're right, but I highlighted only half the story: my issue is that some tasks never end. I don't know how to go about framing the `submit()` with a timeout – Philippe Blayo Sep 06 '13 at 08:56
  • @PhilippeBlayo That's not something that is possible with submit. If your task never ends, then the problem is in the `Callable`. If you need the thread to end, you can always try calling `cancel()` on the `Future`. – Sotirios Delimanolis Sep 06 '13 at 12:21
  • If you give small timeout, say 100ms, then it will throw TimeoutException, which you can catch and do a no-op to mimic fire and forget behavior. – timekeeper Apr 05 '19 at 10:11
6

dont need the future object if you have to forget it i.e. dont care about the future of the thread. :)

ExecutorService executor = Executors.newSingleThreadExecutor();

public void push(Callable<Boolean> task) {
   executor.submit(task);
}

or if you need to use future some time later than :-

ExecutorService executor = Executors.newSingleThreadExecutor();

public void push(Callable<Boolean> task) {
   someCollection.add(executor.submit(task)); // use futures later
}

or just use execute from Executor and pass Runnable, if you dont intent to get the future at all.

ExecutorService executor = Executors.newSingleThreadExecutor();

public void push(Runnable task) {
   executor.execute(task);
}

// execute will invoke default exceptional handler in case of exception, that can be lost in case if you dont get hold of futures in submit method.

leoismyname
  • 407
  • 6
  • 11