0

I have a thread pool with a maximum number of threads of 3. But only one thread is executed, what happened?

public class Volatile {

    private volatile static boolean keepA = true;
    private static boolean keepB = true;

    private static ExecutorService executor = new ThreadPoolExecutor(1,
            3, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>() );

    public static void main(String[] args) {
        executor.execute(() -> {
            while (keepA) {
                System.out.println("keepA running...");
            }
            System.out.println("keepA stop!!!!!!");
        });
        executor.execute(() -> {
            while (keepB) {
                System.out.println("keepB running...");
            }
            System.out.println("keepB stop!!!!!!");
        });
        executor.execute(() -> {
            keepA = false;
            keepB = false;
        });
        while (true) {

        }
    }
}

result

keepA running...
keepA running...
keepA running...
......

dai
  • 1,025
  • 2
  • 13
  • 33

2 Answers2

3

The non-core threads will only be started when the queue is full (and you have an unbounded queue, so that never happens).

As per Javadoc:

Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:

  • If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.
  • If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.
  • If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
Community
  • 1
  • 1
Thilo
  • 257,207
  • 101
  • 511
  • 656
1

The first parameter to ThreadPoolExecutor is the initial amount of threads running in parallel. You have set it to 1. Change it to 3 and try again. This size should grow only when the queue is full, but your queue is of infinite size and is never full.

public ThreadPoolExecutor(int corePoolSize,
              int maximumPoolSize,
              long keepAliveTime,
              TimeUnit unit,
              BlockingQueue<Runnable> workQueue)

Creates a new ThreadPoolExecutor with the given initial parameters and default rejected execution handler.

Parameters:

  • corePoolSize - the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set

  • maximumPoolSize - the maximum number of threads to allow in the pool

  • keepAliveTime - when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.

  • unit - the time unit for the keepAliveTime argument

  • workQueue - the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.

Throws:

  • IllegalArgumentException - if one of the following holds:

    `corePoolSize < 0`
    `keepAliveTime < 0`
    `maximumPoolSize <= 0`
    `maximumPoolSize < corePoolSize` 
    
  • NullPointerException - if workQueue or threadFactory is null

Shloim
  • 5,281
  • 21
  • 36