java线程池总结(ThreadPoolExecutor与Executors特性及使用)

Posted 小艾路西里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java线程池总结(ThreadPoolExecutor与Executors特性及使用)相关的知识,希望对你有一定的参考价值。

1. 线程池简介

线程池是指预先创建好一定数量的线程对象,存入缓冲池中,需要用的时候直接从缓冲池中取出,线程结束之后会再回到缓冲池中

线程池在java中用ThreadPoolExecutor实现

线程池的优点

① 提高线程的利用率
② 提高响应速度
③ 便于统一管理线程对象
④ 可以控制最大的并发数

2. 线程池的使用

在这里插入图片描述

(1) 使用原生的ThreadPoolExecutor

① ThreadPoolExecutor7个参数的作用

corePoolSize:核心池的大小

maximumPoolSize:线程池的最大容量:当核心池大小不够用时再加上拓展出的数量

keepAliveTime:线程存活时间:在没有任务可执行的情况下(就绪队列也为空)备份线程存活的时)(必须是线程池中的数量大于 corePoolSize,才会生效,也就是拓展出的线程的存活时间)

TimeUnit:存活时间单位

BlockingQueue:等待队列,存储等待执行的任务

ThreadFactory:线程工厂,用来创建线程对象

RejectedExecutionHandler:拒绝策略:当线程池达到最大容量后,拒绝提取线程的操作

4种等待队列

阻塞队列是用来存储等待执行的任务

1. ArrayBlockingQueue:基于数组的先进先出队列,创建时必须指定大小
2. LinkedBlockingQueue:基于链表的先进先出队列,创建时可以不指定大小,默认值时 Integer.MAX_VALUE
3. SynchronousQueue:它不会保持提交的任务,而是直接新建一个线程来执行新来的任务
4. PriorityBlockingQueue:具有优先级的阻塞队列

4种拒绝策略

1. AbortPolicy:直接抛出异常
2. DiscardPolicy:放弃任务,不抛出异常(多出来的线程默默丢弃)
3. DiscardOldestPolicy:尝试与等待队列中最前面的任务去争夺,不抛出异常
4. CallerRunsPolicy:谁调用谁处理(比如main方法调用线程池,则将多出来的线程交给main线程去完成任务)

② ThreadPoolExecutor的使用

public class Test {
    public static void main(String[] args) {
    
        Executor executorService = null;
        try {
            executorService = new ThreadPoolExecutor( 
                    5,  // 核心池容量
                    7, // 最大容量
                    1, // 存活时间
                    TimeUnit.SECONDS, // 时间单位
                    new ArrayBlockingQueue<>(2), // 等待队列,这里设置的容量为2
                    Executors.defaultThreadFactory(), // 线程创建工厂,这里使用的是Executors工具类的默认线程工厂
                    new ThreadPoolExecutor.AbortPolicy() // 处理异常的方式,这里采用抛出异常
            );
            System.out.println("===");

            for (int i = 0; i < 10; i++) {
                executorService.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"执行ing");
                });
            }
        } catch (Exception e) {
            System.out.println("超出了最大容量");
            e.printStackTrace();
        }
    }
}

(2) 使用Executors 工具类

Executor接口的3种实现

newSingleThreadExecutor(); // 单一线程池
newFixedThreadPool(int nThreads); // 固定数量线程池
newCachedThreadPool(); // 缓存线程池,数量随机,由电脑配置决定

从下列源码中可以看出,这3种线程池都是实例化的ThreadPoolExecutor,只是参数不同

NewSingleThreadExecutor
在这里插入图片描述
NewFixedThreadPool(int nThreads)
在这里插入图片描述
NewCachedThreadPool()
在这里插入图片描述

① NewSingleThreadExecutor()的使用

public class Test {
    public static void main(String[] args) {
        Executor executorService = Executors.newSingleThreadExecutor(); // 单一线程池
        for (int i = 0; i < 10; i++) {
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName()+"执行ing");
            });
        }
    }
}

同一个线程完成任务
在这里插入图片描述

② NewFixedThreadExecutor()的使用

 Executor executorService = Executors.newFixedThreadPool(5); // 固定数量线程池 创建5个
        for (int i = 0; i < 10; i++) {
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName()+"执行ing");
            });
        }

多个线程(这里是5个)完成任务
在这里插入图片描述

③ NewCachedThreadExecutor()的使用

 ExecutorService executorService = Executors.newCachedThreadPool(); // 缓存线程池
        for (int i = 0; i < 10; i++) {
            executorService.execute(()->{
                System.out.println(Thread.currentThread().getName()+"执行ing");
            });
        }

可见也是多个线程去执行任务
在这里插入图片描述

以上是关于java线程池总结(ThreadPoolExecutor与Executors特性及使用)的主要内容,如果未能解决你的问题,请参考以下文章

java 线程池总结

Java线程池学习总结

java所提供的线程池有几种之线程池总结

java并发-线程池总结

Java线程池总结

java 线程池 spring线程池 多线程知识总结