JDK-7132378 : Race in FutureTask if used with explicit set and get ( not Runnable )
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2012-01-23
  • Updated: 2014-05-02
  • Resolved: 2012-05-09
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u40Fixed 8 b25Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
This issue came up on the jdk7u-dev mailing list, but is applicable to JDK8 too.
  http://mail.openjdk.java.net/pipermail/jdk7u-dev/2012-January/001439.html

Race explanation:

1. When FutureTask.run() is not used, and only FutureTask.set() is
used, FutureTask.set() will race with FutureTask.get().  The race is
evidenced by the initial call to FutureTask.get() returning the
unassigned null value just before it should have seen the assigned
value.  A second call to FutureTask.get() will see the proper value.

2. Because FutureTask.run() is not used, Sync.runner is always null,
and therefore Sync.acquireSharedInterruptibly(), the guard in
Sync.innerGet(), could take the fast path when it calls
Sync.innerIsDone().

3. Over in Sync.innerSet(), the call to Sync.releaseShared(), sets
Sync.runner to null, which in the case of never setting runner to
begin with, is too late to make Sync.acquireSharedInterruptibly()
cause Sync.innerGet() take a slower path.

4. Hence, Sync.innerGet() returns after RAN state is set, but it can
return just before Sync.innerSet() sets the value.

To repeat, if a client uses FutureTask as an implementation of Future
instead of Runnable, this race will happen.  If the client uses it as
an implementation of Runnable, all seems to be well.

Comments
EVALUATION Changeset: f9fb8c4b4550 Author: dl Date: 2012-01-30 11:44 +0000 URL: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/f9fb8c4b4550 7132378: Race in FutureTask if used with explicit set ( not Runnable ) Reviewed-by: chegar, dholmes ! src/share/classes/java/util/concurrent/FutureTask.java + test/java/util/concurrent/FutureTask/DoneTimedGetLoops.java + test/java/util/concurrent/FutureTask/ExplicitSet.java
30-01-2012