FULL PRODUCT VERSION :
java version " 1.7.0_04 "
Java(TM) SE Runtime Environment (build 1.7.0_04-b22)
Java HotSpot(TM) Client VM (build 23.0-b21, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Not related
A DESCRIPTION OF THE PROBLEM :
When creating ScheduledThreadPoolExecutor with corePoolSize=0 and submiiting task using scheduleAtFixedRate then executor endlessly create tasks.
A simple code below demonstrate the problem:
A ScheduledThreadPoolExecutor is created with schedule=0.
A delayed task is scheduled to far in the future (30 hours).
After 10 seconds of running about 38K threads where created (this hang our system)
When changing schedule to 1 then everything is run as expected
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the simple code below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Number of created threads should be 1
Expected output:
Time offset 0(s)] threads count=1
Time offset 1(s)] threads count=1
Time offset 2(s)] threads count=1
Time offset 3(s)] threads count=1
Time offset 4(s)] threads count=1
Time offset 5(s)] threads count=1
Time offset 6(s)] threads count=1
Time offset 7(s)] threads count=1
Time offset 8(s)] threads count=1
Time offset 9(s)] threads count=1
ACTUAL -
Thousands of threads are created per second
Output:
Time offset 0(s)] threads count=1
Time offset 1(s)] threads count=3952
Time offset 2(s)] threads count=8247
Time offset 3(s)] threads count=12755
Time offset 4(s)] threads count=17007
Time offset 5(s)] threads count=21268
Time offset 6(s)] threads count=25671
Time offset 7(s)] threads count=30016
Time offset 8(s)] threads count=34334
Time offset 9(s)] threads count=38709
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class STPE_EndlesslyCreateThreads {
public static void main(String[] args) throws InterruptedException {
final AtomicInteger threadsCounter = new AtomicInteger();
ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(0, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
threadsCounter.incrementAndGet();
return t;
}
});
threadPoolExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
}
}, 30, 30, TimeUnit.HOURS);
long now = System.currentTimeMillis();
Thread.sleep(1);
while ((System.currentTimeMillis()-now) < 10*1000) {
System.out.println( " Time offset " + (System.currentTimeMillis() - now) /1000 + " (s)] threads count= " + threadsCounter);
Thread.sleep(1000);
}
threadPoolExecutor.shutdown();
threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.HOURS);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Change corePoolSize to 1