java 多线程 线程池
- ThreadPoolExecutor
- AbstractExecutorService
- ExecutorService
- Executor
以上就是多线程核心的4个类
他们的关系 ThreadPoolExecutor extends AbstractExecutorService implements ExecutorService implements Executor
最终是由Executor execute()执行线程
创建线程池 有两种方式
第一种方式
newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
这种方式就是可以自己选择自己需求的线程池使用
第二种方式
直接 使用最最上面一层 ThreadPoolExecutor 进行线程池创建
他的使用 有点像 newFixedThreadPool 也是创建定长的线程池,控制最大处理线程数,超出线程放在队列等待
下面只介绍第二种方式,第一种方式可以自行 google和baidu
ThreadPoolExecutor
- ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, BlockingQueue)
- ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, BlockingQueue, ThreadFactory)
- ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, BlockingQueue, RejectedExecutionHandler)
- ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, BlockingQueue , ThreadFactory, RejectedExecutionHandler)
参数
上面就是官方ThreadPoolExecutor所有构造方法
参数 | 解析 |
---|---|
corePoolSize | 设置同时处理最大的线程核数 |
maximumPoolSize | 设置线程池最大的线程总数 |
keepAliveTime | 设置允许空余线程存活的时间 |
unit | 时间单位 |
BlockingQueue | 设置储存队列 |
ThreadFactory | 设置线程工厂设置 线程各种属性 |
RejectedExecutionHandler | 这个属性当存储队列满了,最大线程数满载的时候,还有新增的线程就是报错触发这个方法进行相应的处理 |
这个几个参数的意思
corePoolSize = 5 同时最大处理的线程数, 如果同时进来4个线程, 那么 4 < 5这个时候就可以同时将这个4个线程同时处理,那么就是还有一个空闲线程,如果再进来一个新线程,程序还是会加进 线程池里面处理,这个时候就是线程池处理最大的 并发数了 , 要是这个时候 再进来一个新线程,这个时候就是 设置BlockingQueue储存队列了,如果有设置长度为 5 那么就是说明储存队列 只能储存5个新线程,那么就把新线程加到队列里面 ,当前面的线程处理完就会从储存队列里面提取线程进行处理,如果没有设置长度,默认是Integer.MAX_VALUE就是最大,这种情况就不说了。当储存队列已经满了,再进来一个新的线程,这个时候怎么办, 这个时候设置 maximumPoolSize = 5,设置最大处理的线程总数,他的效果就是当储存队列满了,才会去激活 去处理新进来的线程 , 如果maximumPoolSize线程也已经满载了, 就是说默认线程数 满了,队列满了,最大线程数也满了,这个时候程序会触发RejectedExecutionHandler接口rejectedExecution方法,这个进行异常处理,如果没有配置这个方法,程序就是出现错误异常
,以上的流程就是线程池 处理的流程
看不懂文字看看下面简单的流程图
那么keepAliveTime 这个参数是什么意思呢
when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating
这个是官方的解释
意思就是 当前的开启总线程数量 > 核数线程数量 那么多余的空闲线程存活时间 ,这个什么意思呢
总线程 10 > 核数线程 5 ,keepAliveTime = 5s 那么空闲的剩下5个线程就在 5s 后进行回收 ,
讲 了这么多 直接上代码
代码块
public static void main(String[] args) {
//创建线程池 核数线程5 最大总线程 10 线程存活时间 10s 缓存队列 5
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 7, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2), new MyThreadFactory() , new MyRejectedExecutionHandler());
for (int i = 0; i < 10; i++)
//处理线程
threadPoolExecutor.execute(new MyRunnable(i));
System.out.println("核心线程数:" + threadPoolExecutor.getCorePoolSize());
System.out.println("线程数总数:" + threadPoolExecutor.getMaximumPoolSize());
System.out.println("队列线程数:" + threadPoolExecutor.getQueue().size());
System.out.println("当前活动线程数:" + threadPoolExecutor.getActiveCount());
}
static class MyRunnable implements Runnable {
int flag = 0;
public MyRunnable(int flag) {
this.flag = flag;
}
@Override
public void run() {
System.out.println("开始运行线程:" + flag);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("线程终止:" + flag);
}
System.out.println("运行结束:" + flag);
}
}
static class MyRejectedExecutionHandler implements RejectedExecutionHandler{
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("处理已满");
}
}
static class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
}
运行结果
处理已满
开始运行线程:7
开始运行线程:4
开始运行线程:1
开始运行线程:8
开始运行线程:6
核心线程数:2
开始运行线程:5
开始运行线程:0
线程数总数:7
队列线程数:2
当前活动线程数:7
运行结束:6
运行结束:7
运行结束:0
运行结束:1
运行结束:5
运行结束:4
开始运行线程:3
开始运行线程:2
运行结束:8
运行结束:3
运行结束:2
程序首先出 0和1线程 之后 将2和3加缓存队列 之后4 , 5 , 6 , 7 , 8 , 9 线程开启到之后线程数量 , 剩下10没有打印就是因为触发RejectedExecutionHandler异常 ,
以上就是我个人对 ThreadPoolExecutor 一些见解,
欢迎转载,谢谢!