United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 7091003 ScheduledExecutorService never executes Runnable with corePoolSize of zero
7091003 : ScheduledExecutorService never executes Runnable with corePoolSize of zero

Details
Type:
Bug
Submit Date:
2011-09-15
Status:
Closed
Updated Date:
2012-08-28
Project Name:
JDK
Resolved Date:
2012-05-09
Component:
core-libs
OS:
linux_ubuntu
Sub-Component:
java.util.concurrent
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
8

Related Reports
Backport:

Sub Tasks

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

http://hg.openjdk.java.net/jdk8/tl/jdk/rev/8dab38c07b6b
                                     
2011-09-23
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
                                     
2011-09-23
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);
>     }
>
>     /**
                                     
2011-09-21
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.
                                     
2011-09-20



Hardware and Software, Engineered to Work Together