Why does ExecutorService.submit(Runnable task) return Future<?> rather than Future<Void>?
Asked Answered
S

3

21

The ExecutorService has the following method:

Future<?> submit(Runnable task)

But since this Future's get method will always return null wouldn't the following signature be more appropriate?

Future<Void> submit(Runnable task)

Sunglasses answered 15/5, 2017 at 8:7 Comment(0)
T
4

Jdk 1.8 inside submit method implementation void is used while in jdk1.6 it was Object .My understanding is it is more appropriate to use void that's why it is changed in jdk1.7/1.8.Only to support the interface not changing it

 public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

and in JDK 1.6

 public Future<?> submit(Runnable task) {
       if (task == null) throw new NullPointerException();
       RunnableFuture<Object> ftask = newTaskFor(task, null);
       execute(ftask);
        return ftask;
   }
Thorazine answered 15/5, 2017 at 8:27 Comment(1)
Yes, I get that they don't want to change the interface afterwards. But why was it defined the way it is in the first place? Void type was available since Java 1.1. So I guess it was just a mistake.Sunglasses
B
2

Notice that Runnable's run method returns void primitive and not Void type. For that reason, Future cannot have a Void type and the solution was to make it a wildcard. Note that Future is from java 1.5 whereas Runnable is from 1.0. They wouldn't change run's return type to conform to the Future due to legacy code reasons.

Bohs answered 15/5, 2017 at 8:27 Comment(1)
Future<Void>'s get method will always return null which is exactly what is asked for in this situation. Future<?> can return any object, when actually it will always return null in this particular case, as stated in the javadoc of the submit method. So Future<Void> would have been the right choice here. Analogous, if run would have returned double a Future<Double> would be appropriate rather than a Future<?>.Sunglasses
T
-1

Because ExecutorService's Future interface is created for get a return data from another thread not for just run it. Future<Void> submit(Runnable task) works same as new Thread(runnable).start(), the return of null is meaningfull for some cases.

Edit : Think you need to close a thread after 20 minutes. How would you do that when you have a return value void ?

Future<Void> future = execService.submit(operation);
execService.shutdown();
opResult = future.get(20, TimeUnit.MINUTES);

This code must give error because there is no return on future. But if it return a null the execService controller object will know the shutdown is happened. Or if it not return anything in 20 min execService.shutdownNow() can be used.

Tap answered 15/5, 2017 at 8:15 Comment(7)
If it was Future<Void>, it would work exactly the same way as it does now.Tlingit
How could you return Void from call method ?Grate
Void method() { return null; }Tlingit
return null is not same with void signed method. Op is asking for no return valueGrate
First, I mean java.lang.Void (abbreviated as Void after imports), not void, same as OP does. Second, OP isn't asking for no return value.Tlingit
I'm talking about java.lang.Void. If you declare Void you must return null. But OP's problem is with returned null value. Returning null is not true for Void logic.Grate
@BurakAkyıldız my problem is not with returned null value but with the method signature. Future<Void> would be more appropriate for a Future that always returns null.Sunglasses

© 2022 - 2024 — McMap. All rights reserved.