Michael
Michael

Reputation: 304

Why doesn't ScheduledExecutorService spawn threads as needed?

In my application I use ScheduledExecutorService, but only one thread is spawned to handle the scheduled tasks. Is this because ScheduledExecutorService does not spawn threads to handle the pending tasks?

Here is a code snippet that will output only "run() 1" instead of the expected "run() 1" followed by "run() 2" ... "run() 10."

public class App {

    public static void main(String[] args) {
        int N = 10;
        Runnable runner = new Runnable() {

            public void run() {
                foo();
            }
        };
        for (int i = 0; i < N; i++) {
            executor.schedule(runner, i, TimeUnit.MILLISECONDS);
        }
    }

    private static void foo() {
        System.out.println("run() " + (++n));
        synchronized (executor) {
            try {
                executor.wait();
            } catch (InterruptedException ex) {
                Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("finished()");
    }
    private static Logger logger = Logger.getLogger(App.class.getName());
    private static int n = 0;
    private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
}

Upvotes: 11

Views: 8344

Answers (2)

JB Nizet
JB Nizet

Reputation: 691715

There is only one thread because you create the thread pool with Executors.newScheduledThreadPool(1), which means that the thread pool contains only 1 thread. If you want 10 threads, pass 10 as argument. Note that the documentation of ScheduledThreadPoolExecutor, which is what this method returns, explicitly says that the thread pool has a fixed size.

Upvotes: 15

Jim Garrison
Jim Garrison

Reputation: 86774

From the javadoc for ScheduledThreadPoolExecutor:

While this class inherits from ThreadPoolExecutor, a few of the inherited tuning methods are not useful for it. In particular, because it acts as a fixed-sized pool using corePoolSize threads and an unbounded queue, adjustments to maximumPoolSize have no useful effect. Additionally, it is almost never a good idea to set corePoolSize to zero or use allowCoreThreadTimeOut because this may leave the pool without threads to handle tasks once they become eligible to run.

In other words, maximumPoolSize == corePoolSize. You set corePoolSize to 1, so that's all it will spawn.

Upvotes: 6

Related Questions