|
Quick Lists
|
|
Bug ID:
|
6267833
|
|
Votes
|
1
|
|
Synopsis
|
Incorrect method signature ExecutorService.invokeAll()
|
|
Category
|
java:classes_util_concurrent
|
|
Reported Against
|
|
|
Release Fixed
|
mustang(b51)
|
|
State
|
10-Fix Delivered,
Verified,
bug
|
|
Priority:
|
3-Medium
|
|
Related Bugs
|
|
|
Submit Date
|
10-MAY-2005
|
|
Description
|
FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
A DESCRIPTION OF THE PROBLEM :
The typed method signature for the invokeAll() call in ExecutorService is incorrect. It should be declared:
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
I have included a tiny test program which shows the compilation error
that occurs because of the method declaration. The method is declared to
take a collection of exactly the type Callable, which is improper. As the
implementation of the invokeAll() does not need to add to the collection it
is almost certainly not needed, but requires developers to reassign objects
to expose the proper type when not building a new collection.
a better declaration would be:
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
This change makes the class much more flexible, and the change should be
made to the other similar methods in the class:
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout,
TimeUnit unit)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.*;
import java.util.concurrent.*;
public class Test implements Callable<Object> {
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
Test test = new Test();
// This does not work because of the invokeAll() declaration.
service.invokeAll(Collections.singleton(test));
// This does but the assignment should not be necessary.
Callable<Object> callable = test;
service.invokeAll(Collections.singleton(callable));
}
public Object call() throws Exception {
System.out.println("Called.");
}
}
---------- END SOURCE ----------
xxxxx@xxxxx 2005-05-10 09:38:27 GMT
Posted Date : 2005-08-03 05:16:40.0
|
|
Work Around
|
For the particular case of the submitter's program,
a slightly simpler workaround is possible, using the
syntax
Collections.<Callable<Object>>singleton(x)
-----------------------------------------------------------------
import java.util.*;
import java.util.concurrent.*;
public class Bug implements Callable<Object> {
public static void main(String[] args) throws Throwable {
ExecutorService service = Executors.newSingleThreadExecutor();
Bug x = new Bug();
// This does not work because of the invokeAll() declaration
//service.invokeAll(Collections.singleton(x));
// This workaround works but should not be necessary
service.invokeAll(Collections.<Callable<Object>>singleton(x));
service.shutdown();
}
public Object call() throws Exception {
System.out.println("Called.");
return null;
}
}
-----------------------------------------------------------------
|
|
Evaluation
|
The JSR-166 expert group alumni agrees that the change:
- is binary compatible.
- is source compatible for *users* of an ExecutorService
- requires minor source code changes for the small set of developers
who have implemented ExecutorService without inheriting the
default implementations in AbstractExecutorService. The set of
affected developers are developers creating sophisticated
thread pool applications, putting them into the
"concurrency rocket scientist" category. They will generally
appreciate this change. The possible compiler error is trivial
to fix in the source code.
There is always a tradeoff if/when such a slightly incompatible change
is worth making. Consensus is that this change is worth making now.
Posted Date : 2005-08-16 20:28:41.0
|
|
Comments
|
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |