JDK-7091003 : ScheduledExecutorService never executes Runnable with corePoolSize of zero
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2011-09-15
  • Updated: 2015-09-21
  • 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
7u4Fixed 8 b08Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
Test case exhibits bug on:
Linux dt-000839 2.6.35-30-generic #56-Ubuntu SMP Mon Jul 11 20:01:08 UTC 2011 x86_64 GNU/Linux
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) 64-Bit Server VM (build 21.0-b17, mixed mode)

and

Linux wilf 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:02:55 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
OpenJDK Runtime Environment (IcedTea6 1.10.2) (6b22-1.10.2-0ubuntu1~11.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)

Test case does *not* exhibit bug on:
Linux wilf 2.6.38-11-generic #48-Ubuntu SMP Fri Jul 29 19:02:55 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
See comments in Runtime version


A DESCRIPTION OF THE PROBLEM :
A Runnable submitted to a ScheduledExecutorService having a core pool size of zero is never executed.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
"Hello" is printed to stdout
ACTUAL -
The Runnable is never executed

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

class ScheduledExecutorTest {
    public static void main(String[] args) throws InterruptedException {
        final ScheduledExecutorService ex = Executors.newScheduledThreadPool(0);
        ex.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        }, 1, TimeUnit.SECONDS);

        ex.shutdown();
        ex.awaitTermination(5, TimeUnit.SECONDS);
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Increase the corePoolSize to a value greater than zero.

Comments
EVALUATION Changeset: 8dab38c07b6b Author: dl Date: 2011-09-23 14:24 +0100 URL: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/8dab38c07b6b 7091003: ScheduledExecutorService never executes Runnable with corePoolSize of zero Reviewed-by: dholmes, chegar ! src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java ! src/share/classes/java/util/concurrent/ThreadPoolExecutor.java + test/java/util/concurrent/ScheduledThreadPoolExecutor/ZeroCorePoolSize.java
23-09-2011

EVALUATION http://hg.openjdk.java.net/jdk8/tl/jdk/rev/8dab38c07b6b
23-09-2011

SUGGESTED FIX Prfovided by Doug Lea: Index: jsr166/src/main/java/util/concurrent/ScheduledThreadPoolExecutor.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/ScheduledThreadPoolExecutor.java,v retrieving revision 1.62 diff -r1.62 ScheduledThreadPoolExecutor.java 306c306 < prestartCoreThread(); --- > ensurePrestart(); 322c322 < prestartCoreThread(); --- > ensurePrestart(); % cvs diff jsr166/src/main/java/util/concurrent/ThreadPoolExecutor.java Index: jsr166/src/main/java/util/concurrent/ThreadPoolExecutor.java =================================================================== RCS file: /export/home/jsr166/jsr166/jsr166/src/main/java/util/concurrent/ThreadPoolExecutor.java,v retrieving revision 1.124 diff -r1.124 ThreadPoolExecutor.java 1519a1520,1531 > * Same as prestartCoreThread except arranges that at least one > * thread is started even if corePoolSize is 0. > */ > void ensurePrestart() { > int wc = workerCountOf(ctl.get()); > if (wc == 0) > addWorker(null, false); > else if (wc < corePoolSize) > addWorker(null, true); > } > > /**
21-09-2011

EVALUATION It seems that in the re-work that was done for Java 7 we dropped this corner case. STPE.delayedExecute will add the task to the work queue and invoke prestartCoreThread. But prestartCoreThread checks for the worker count (0) being less than corePoolSize (0) and as that is not the case nothing happens. So we have a task in the queue but no thread waiting to execute it. For STPE when the queue is not empty there must always be at least one thread waiting on the queue.
20-09-2011