Java线程池

栏目: Java · 发布时间: 6年前

内容简介:Java线程池(以线程池参数最多的构造函数(线程池的存在,默认会阻止主程序的自动退出。销毁掉线程池中的全部线程后,主程序才可以顺利退出。

Java线程池( java.util.concurrent.ThreadPoolExecutor )实现了接口 java.util.concurrent.ExecutorService ,将线程资源缓存起来,实现了线程的复用。

示例代码

package bj;

import io.vavr.control.Try;

import java.time.LocalTime;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2018/12/7 上午10:05
 */
public class FooTest {

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 6, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), new ThreadFactory() {
            private int count = 0;

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, String.format("Thread[%d]", ++count));
            }
        }, (r, executor1) -> System.out.println("Ignored: " + r));
        executor.allowCoreThreadTimeOut(true);
        IntStream.range(0, 10).forEach($ -> executor.execute(() -> {
            Try.run(() -> Thread.sleep(1000)).getOrElseThrow((Supplier<RuntimeException>) RuntimeException::new);
            System.out.println(String.format("%s Progress: %d Thread: %s", LocalTime.now(), $, Thread.currentThread().getName()));
        }));
    }
}

示例输出

Ignored: bj.FooTest$$Lambda$3/783286238@27082746
14:13:53.247 Progress: 0 Thread: Thread[1]
14:13:53.247 Progress: 2 Thread: Thread[3]
14:13:53.247 Progress: 8 Thread: Thread[6]
14:13:53.247 Progress: 3 Thread: Thread[4]
14:13:53.248 Progress: 1 Thread: Thread[2]
14:13:53.248 Progress: 7 Thread: Thread[5]
14:13:54.252 Progress: 5 Thread: Thread[6]
14:13:54.252 Progress: 6 Thread: Thread[3]
14:13:54.252 Progress: 4 Thread: Thread[1]

Process finished with exit code 0

线程池各参数讲解

以线程池参数最多的构造函数( java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler) )为例

  • corePoolSize 核心池大小。核心池直接开辟空间
  • maximumPoolSize 最大池(核心池+普通池)大小 线程数量超过这个大小,会拒绝执行
  • keepAliveTime 线程存活时间 线程过了存活时间会自动销毁,默认情况下核心池例外
  • unit 线程存活时间单位
  • workQueue 工作队列 任务会在workQueue排队
  • threadFactory 线程工厂 如何创建线程。可以指定线程名称、记录日志等
  • handler 拒绝执行策略 默认抛异常,不执行

线程池基本工作流程

  1. 创建线程池,核心池分配满线程
  2. 新任务进入,放入核心池,开始执行
  3. 新任务进入,核心池已满,放入执行队列
  4. 新任务进入,执行队列已满,新任务放入普通池立即执行
  5. 新任务进入,线程数量超过最大池大小,拒绝执行
  6. 任务执行完毕,进入等待状态。普通池的线程超时后自动销毁
  7. 如果 allowCoreThreadTimeOut 设为 true ,核心池中的线程超时后自动销毁

示例程序中,各任务的流向

  1. 任务1,放入核心池执行
  2. 任务2,放入核心池执行
  3. 任务3,放入核心池执行
  4. 任务4,放入核心池执行
  5. 任务5,核心池已满,放入执行队列等待
  6. 任务6,核心池已满,放入执行队列等待
  7. 任务7,核心池已满,放入执行队列等待
  8. 任务8,核心池和指定队列都已满,放入普通池立即执行
  9. 任务9,核心池和指定队列都已满,放入普通池立即执行
  10. 任务10, 核心池+普通池已达上限,任务被拒绝执行

线程池任务执行完成后自动销毁全部线程

线程池的存在,默认会阻止主程序的自动退出。销毁掉线程池中的全部线程后,主程序才可以顺利退出。

实现线程池任务全部接触后,自动销毁全部线程,有两种方式:

executor.allowCoreThreadTimeOut(true);
executor.setCorePoolSize(0);

文章首发: https://baijifeilong.github.io


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

三位一体

三位一体

[美]迈克尔·马隆 / 黄亚昌 / 浙江人民出版社 / 2015-4 / 98.90

[内容简介] ●本书讲述了罗伯特•诺伊斯、戈登•摩尔和安德鲁•格鲁夫如何缔造了世界上最重要公司的故事。公司的“外交家”诺伊斯被视为圣父、“思想家”摩尔被视为圣灵、“行动家”格鲁夫被视为圣子,这个三位一体的组合创下了企业管理中的奇迹,开创了一个价值万亿美元的产业,将一家初创企业打造成为千亿美元量级的巨型公司。 ●本书作者迈克尔•马隆在接触空前数量的企业档案的基础上,揭示了英特尔公司无处不......一起来看看 《三位一体》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具