[concurrency-interest] Executors.newSingleThreadScheduledExecutor()

Hanson Char hanson.char at gmail.com
Thu Apr 7 01:00:50 EDT 2005

The javadoc of Executors.newSingleThreadScheduledExecutor():

"Creates a single-threaded executor that can schedule commands to run
after a given delay, or to execute periodically. (Note however that if
this single thread terminates due to a failure during execution prior
to shutdown, a new one will take its place if needed to execute
subsequent tasks.) Tasks are guaranteed to execute sequentially, and
no more than one task will be active at any given time. Unlike the
otherwise equivalent newScheduledThreadPool(1) the returned executor
is guaranteed not to be reconfigurable to use additional threads."

My question is if the single thread terminates due to a failure, do we expect 

1) a new one to take its place so the periodic command will still be
re-scheduled and get executed ?   Or
2) the failure to cause a termination of the periodic execution so the
command will not be re-scheduled ?

I expect (1) but the behave of both JDK1.5_02 and the latest backport
version is (2).  Is this a bug in the code, the javadoc, or my
understanding ?

Please find below some sample test code.


import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Daemon {
    private final ScheduledExecutorService scheduler =
    public Daemon(Runnable command, long period, TimeUnit timeUnit) {
        scheduler.scheduleAtFixedRate(command, 0, period, timeUnit);
    public void shutdown() {

import java.util.Date;
import junit.framework.*;
import java.util.concurrent.TimeUnit;

public class DaemonTest extends TestCase {
	private int count;
    // if error is true, executes only once.
    // if error is false, executes every 1 sec.
    boolean error = true;

	public void test() throws InterruptedException {
		final Runnable beeper = new Runnable() {
			public void run() {
				System.out.println("run at " + new Date());
				if (error)
					throw new RuntimeException("test");
		Daemon s = new Daemon(beeper, 1, TimeUnit.SECONDS);
		Thread.sleep(10 * 1000);

More information about the Concurrency-interest mailing list