ThreadPoolExecutor使用测试2-线程数量达到maximumSize

测试特性

  1. 最大线程数量为n,有界队列为m,当向线程池提交n+m个任务时,线程池中的线程池大小为n

环境

  1. jdk 1.8
  2. maven
<!-- junit test -->
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

测试

测试用例

package concurrent;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import util.StdOut;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * ThreadPoolExecutor测试类
 */
public class ThreadPoolExecutorTest {
    /**
     * 线程池中线程索引
     */
    private final AtomicInteger pooledThreadIdx = new AtomicInteger(0);

    /**
     * 核心线程数
     */
    private final int coreSizeN = 1;

    /**
     * 最大线程数
     */
    private final int maxSizeN = 3;

    /**
     * 任务最大排队数量
     */
    private final int queueSizeM = 10;

    /**
     * 线程池中大于coreSize的线程空闲时间,单位:毫秒
     */
    private final long keepAliveTime = 60L * 1000;

    /**
     * 线程池
     */
    private ThreadPoolExecutor threadPoolExecutor;

    /**
     * 控制线程池任务执行开关
     */
    private final AtomicBoolean pass = new AtomicBoolean(false);

    @Before
    public void before() {
        // 新建线程池
        threadPoolExecutor = new ThreadPoolExecutor(
                coreSizeN,
                maxSizeN,
                keepAliveTime,
                TimeUnit.MILLISECONDS,
                // 任务队列为最大排队为10的任务队列
                new ArrayBlockingQueue<>(queueSizeM),
                // 定制ThreadFactory,定义线程名称,以在多个线程池场景下区分业务线程
                r -> new Thread(r, "executor-tester-" + pooledThreadIdx.getAndIncrement()),

                // 如果排队数量超过10,且线程最大已经达到maximumPoolSize时,再有任务提交时的拒绝策略
                // 一般是直接拒绝:表示服务仅能支撑这么多
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

    /**
     * 测试线程池线程数量等于最大线程数用例
     * @throws InterruptedException
     */
    @Test
    public void testThreadCountGreaterThanCoreSize() throws InterruptedException {
        // 向线程池提交n + m个任务
        submitTask(threadPoolExecutor, pass, maxSizeN + queueSizeM);
        startControlThread(pass, maxSizeN, threadPoolExecutor);
    }

    /**
     * 提交任务到线程池
     * @param threadPoolExecutor 线程池
     * @param pass 任务控制开关
     * @param taskCount 任务数量
     */
    private void submitTask(ThreadPoolExecutor threadPoolExecutor, AtomicBoolean pass, int taskCount) {
        for (int i = 0; i < taskCount; i++) {
            threadPoolExecutor.submit(() -> {
                while (!pass.get()) {
                    StdOut.println(Thread.currentThread().getName() + ": Thread running..." );
                    sleep(1000);
                }
            });
        }
    }

    /**
     * 睡眠
     * @param millis 睡眠时间,单位:毫秒
     */
    public static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 控制线程池中任务执行的线程
     * @param pass 任务执行开关 true:任务执行,false:任务睡眠
     * @param maxSizeN  线程池中最大线程数量
     * @param threadPoolExecutor 线程池
     * @throws InterruptedException
     */
    private void startControlThread(AtomicBoolean pass, int maxSizeN, ThreadPoolExecutor threadPoolExecutor) throws InterruptedException {
        // 控制线程
        Thread controlThread = new Thread(() -> {
            int i = 0;
            while (i++ < 10) {
                // 先将自己睡眠一秒防止线程池还没有“反应过来”就获取活动线程数量为0的问题
                sleep(1000);

                // 睡眠一秒后再获取活动的线程数量应该为1,
                Assert.assertEquals(maxSizeN, threadPoolExecutor.getActiveCount());
                StdOut.println("thread pool running workers: " + threadPoolExecutor.getActiveCount());
            }

            // 将线程中的任务全部放行
            pass.set(true);

            i = 0;
            // 等待大约2秒时间再判断线程池中的活动线程数量应该为0
            // 因为任务已经执行完成了
            while (i++ < 10) {
                sleep(200);
                StdOut.println("thread pool running workers: " + threadPoolExecutor.getActiveCount());
            }
            Assert.assertEquals(0, threadPoolExecutor.getActiveCount());
            StdOut.println("thread pool running workers: " + threadPoolExecutor.getActiveCount());
        });
        controlThread.start();
        controlThread.join();
    }

}

Console输出

executor-tester-0: Thread running...
executor-tester-1: Thread running...
executor-tester-2: Thread running...
executor-tester-2: Thread running...
executor-tester-1: Thread running...
executor-tester-0: Thread running...
thread pool running workers: 3
executor-tester-0: Thread running...
thread pool running workers: 3
executor-tester-2: Thread running...
executor-tester-1: Thread running...
executor-tester-2: Thread running...
executor-tester-1: Thread running...
executor-tester-0: Thread running...
thread pool running workers: 3
executor-tester-2: Thread running...
thread pool running workers: 3
executor-tester-1: Thread running...
executor-tester-0: Thread running...
executor-tester-2: Thread running...
executor-tester-1: Thread running...
executor-tester-0: Thread running...
thread pool running workers: 3
executor-tester-0: Thread running...
thread pool running workers: 3
executor-tester-1: Thread running...
executor-tester-2: Thread running...
executor-tester-2: Thread running...
thread pool running workers: 3
executor-tester-0: Thread running...
executor-tester-1: Thread running...
executor-tester-2: Thread running...
executor-tester-1: Thread running...
executor-tester-0: Thread running...
thread pool running workers: 3
executor-tester-0: Thread running...
executor-tester-1: Thread running...
thread pool running workers: 3
executor-tester-2: Thread running...
executor-tester-1: Thread running...
executor-tester-0: Thread running...
executor-tester-2: Thread running...
thread pool running workers: 3
thread pool running workers: 3
thread pool running workers: 3
thread pool running workers: 3
thread pool running workers: 3
thread pool running workers: 0
thread pool running workers: 0
thread pool running workers: 0
thread pool running workers: 0
thread pool running workers: 0
thread pool running workers: 0
thread pool running workers: 0
上一篇:ThreadPoolExecutor使用测试3-测试在全部任务终止后,再次向线程池提交任务


下一篇:论文阅读之 DECOLOR: Moving Object Detection by Detecting Contiguous Outliers in the Low-Rank Representation