JUC-ThreadPoolExecutor 线程池初步了解与认识

1.什么是线程池

就是可管理和维护以及分配线程的 容器

2.使用线程池的优点

优化线程的内存开销

3.ThreadPoolExecutor的核心参数

public ThreadPoolExecutor(int corePoolSize,//核心线程数
                          int maximumPoolSize,//最大线程数
                          long keepAliveTime,//线程空闲时间
                          TimeUnit unit,//时间单位
                          BlockingQueue<Runnable> workQueue,//任务队列
                          ThreadFactory threadFactory,//线程工厂
                          RejectedExecutionHandler handler//拒绝策略) 

4.线程池的执行顺序

  • 当线程数小于核心线程数,且存在未执行的任务,创建线程。
  • 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
  • 当线程数大于等于核心线程数,且任务队列已满,若线程数小于最大线程数,创建线程。
  • 若线程数等于最大线程数,则执行拒绝策略

5.线程池的参数详解

①corePoolSize:核心线程数(一般与线程具体参与的业务有关-计算类型/读写类型)

计算类型-CPU密集型 ;读写类型-IO密集型

②maximumPoolSize:最大线程数-考虑项目业务最大程度上最大容量的线程数

③keepAliveTime:最大空闲时间,非核心线程超过最大空闲时间则释放

④unit:时间单位-秒-分钟-时-天

⑤workQueue:当核心线程都处于工作,任务进行队列中等待

⑥threadFactory:线程工厂

⑥handler:拒绝策略-抛异常-不抛异常-自定义策略

当线程数已经达到maxPoolSize,且队列已满,会拒绝新任务。默认会抛出异常

6线程池的工作机制

前提:在如下场景中,核心线程数为2,最大线程数为4,任务队列为2

刚开始,没有任何的线程和任务

此时,来了一个任务一, 线程池(公司)生产一个线程(小王)处理任务一

此时,又来了任务二, 线程池(公司)生产一个线程(小李)处理任务二

此时,陆续来了任务三,任务四,由于当前线程数(2)等于核心线程数(2),且任务队列未满时,将任务陆续放入任务队列。

此时,来了任务5,任务队伍已满

 任务队列已满,且核心线程数已满,线程池(公司)招临时工小怡处理任务五

又来了任务六,此时线程数3(2+1),未超过最大线程数4,可以再招一个临时工小皮处理任务六

此时又来了一个任务七 ,最大线程数已达极限任务队列已满,调用拒绝策略处理任务七

---以上是我的初步了解线程池机制的动画图,如有帮助可以点赞支持一下!!!感谢观看 

7.自定义线程池

项目在启动的时候,@Bean方法返回的ThreadPoolExecutor 对象也会立马存入容器当中!

@Configuration
@Data
public class ThreadPoolExecutorConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(){
        //线程工厂
        ThreadFactory threadFactory = new ThreadFactory() {
            private int count = 1;
            @Override
            public Thread newThread(@NotNull Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("线程"+ count);
                count++;
                return thread;
            }
        };
        //新建ThreadPoolExecutor对象并配置相关参数
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                4,
                100,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(4),
                threadFactory
        );
        return threadPoolExecutor;
    }
}

自定义线程处理方法

get():查看线程池的相关信息

add():新增线程

CompletableFuture提供了静态方法来创建一个异步操作:

public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)

8此方法Runnable函数式接口类型为参数,没有返回结果,使用指定的线程池运行

@RestController
@RequestMapping("/queue")
@Slf4j
public class QueueController {

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @GetMapping("/add")
    public void add(String name){
        //
        CompletableFuture.runAsync(()->{
            log.info("任务执行中:"+name+",执行人:"+Thread.currentThread());
            try {
                Thread.sleep(600000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },threadPoolExecutor);
    }

    @GetMapping("/get")
    public String get(){
        HashMap<String, Object> map = new HashMap<>();
        int size = threadPoolExecutor.getQueue().size();
        map.put("队列长度",size);
        long taskCount = threadPoolExecutor.getTaskCount();
        map.put("任务总数:",taskCount);
        long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
        map.put("已完成任务数",completedTaskCount);
        int activeCount = threadPoolExecutor.getActiveCount();
        map.put("正在工作的线程数",activeCount);
        return JSONUtil.toJsonStr(map);
    }

}

8.接口文档-测试线程池的工作机制

前提:核心线程数2,最大线程数4,任务队列4

 添加任务---临界情况

此时再添加一个任务,系统抛异常-拒绝策略

 

---面试题 

1.什么是线程池?

线程池就是提前创建若干个线程

2.线程池的优点?

重用存在的线程,减少对象创建的开销

有效地控制最大并发数

3.线程池在开发场景中怎么使用?

使用自定义线程池

4.线程池的7大参数

1.corePoolSize,线程池中常驻核心线程数.
2.maximumPoolSize,线程池中可同时执行的最大线程数。
3.keepAliveTime,执行完阻塞队列任务且无新任务,等待临时线程销毁的时间
4.TimeUnit unit,keepAliveTime单位。
5.BlockingQueue workQueue,任务队列,被提交但是未被立马执行的任务。
6.ThreadFactory threadFactory,生成线程的线程工厂。
7.RejectedExecutionHandler handler,拒绝策略。

5.线程池拒绝策略

AbortPolicy策略:该策略会直接抛出异常,阻止系统正常工作。
CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者线程中,运行当前的被丢弃的任务。
DiscardOleddestPolicy策略: 该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务。
DiscardPolicy策略:该策略默默的丢弃无法处理的任务,不予任何处理。

6.线程池工作机制

7. 核心线程数和最大线程数和工作线程个数的关系? 

工作线程数的个数可能从0最大线程数之间变化,当执行一段时间之后可能维持在核心线程数(corePoolSize),但也不是绝对的,取决于核心线程是否允许被超时回收。

 最大线程数 = 核心线程数 + 临时线程数

8.存活时间keepAliveTime的理解?

工作线程数达到核心线程数时,新来的任务将放到有界堵塞队列中,且一段时间队列满了,程序将创建临时工作线程,当阻塞队列的任务执行完毕且没有新任务提交,临时线程将被销毁。这一段等待销毁的时间叫做存活时间keepAliveTime

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值