通过线程池创建线程

本文介绍两种线程池创建方式:一种是通过ThreadPoolExecutor自定义线程池参数,包括线程数、缓存队列和拒绝策略等;另一种是使用Executors简化创建,但灵活性较低。文章还介绍了线程池的关闭方法及容量动态调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 创建线程池(推荐)
 */
@Test
public void createThreadPoolTask() throws InterruptedException {

    ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            /**
             * 该线程池核心线程数 最小存在数 在创建该线程池时 是没有初始化该线程的
             * 如果在创建线程池时初始化核心线程时需要调用
             * this.prestartAllCoreThreads() 方法初始化核心线程
             */
            1000,
            /**
             * 最高线程数 该线程池可存在的最高线程数
             */
            3000,
            /**
             * 如果有空闲线程 则该空闲线程能够存在最大时间 需要结合TimeUnit使用
             */
            5,
            /**
             * 空闲时间单位
             */
            TimeUnit.SECONDS,
            //线程池缓存队列数
            /**
             * 阻塞队列与队列规则和队列数量
             * workQueue的类型为BlockingQueue<Runnable>,通常可以取下面三种类型:
             * ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小;
             * LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;
             * synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。
             */
            new LinkedBlockingQueue<Runnable>(100000),
            /**
             * 创建Thread的线程工厂 如果在不自定义线程工厂的情况下建议使用Hutool的线程工厂  里面可以自定义线程的属性:
             * ThreadUtil.createThreadFactoryBuilder()xxxxxxxxx .build()
             * 或者Executors.defaultThreadFactory() 该方法来创建线程工厂
             */
            ThreadUtil.createThreadFactoryBuilder().setNamePrefix("111线程名称").build(),
            /**
             * 拒绝任务策略 将使用该策略来处理超出缓存队列出现的情况 根据实际环境进行选择
             * ThreadPoolExecutor.AbortPolicy;//丢弃任务并抛出RejectedExecutionException异常。
             * ThreadPoolExecutor.DiscardPolicy;//也是丢弃任务,但是不抛出异常。
             * ThreadPoolExecutor.DiscardOldestPolicy;//丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
             * ThreadPoolExecutor.CallerRunsPolicy;//由调用线程处理该任务
             */
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 线程池的关闭
     *
     *ThreadPoolExecutor提供了两个方法,用于线程池的关闭,分别是shutdown()和shutdownNow(),其中:
     *
     * shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
     * shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务
     *
     * 线程池容量的动态调整
     * ThreadPoolExecutor提供了动态调整线程池容量大小的方法:setCorePoolSize()和setMaximumPoolSize(),
     *
     * setCorePoolSize:设置核心池大小
     * setMaximumPoolSize:设置线程池最大能创建的线程数目大小
     * 当上述参数从小变大时,ThreadPoolExecutor进行线程赋值,还可能立即创建新的线程来执行任务。
     */


    //初始化核心线程
    threadPoolExecutor.prestartAllCoreThreads();

    for (int i = 1; i < 6000000; i++) {

        if (i % 300 == 0) {
            Thread.sleep(1);
        }

        threadPoolExecutor.execute(() -> System.out.println(Thread.currentThread().getName() + ":  " + 1));

    }

    threadPoolExecutor.shutdown();
}


/**
 * 创建线程池(不推荐)  这样创建的线程不够自定义线程数与规则 容易出现资源耗尽的风险
 */
@Test
public void creatThreadTask() {

    ExecutorService executorService = Executors.newFixedThreadPool(5);
    executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
    executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
    executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
    executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
    executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
    executorService.execute(() -> System.out.println(Thread.currentThread().getName()));
    executorService.shutdown();

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值