ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

浅谈线程池

2022-02-09 15:59:40  阅读:169  来源: 互联网

标签:浅谈 队列 threadPool 任务 线程 new ThreadPoolExecutor


线程池

线程池的使用场景

在方法中直接new一个线程,当如果频繁的调用这个方法,那么就会创建很多线程,这样不仅会消耗系统资源,还会降低系统的稳定性,极其容易搞崩服务器。所以就需要用到线程池

线程池的好处

1.响应速度的提高(任务不需要等待线程的创建,可以直接执行)
2.系统资源消耗降低(重复利用已经创建的线程)
3.线程的可管理性(使用线程池进行统一分配,调优和监控)

线程池的创建

这是几个java自带的功能线程池,已经封装好的,可以直接使用的。
1.可缓存线程池(CachedThreadPool)
2.定长线程池(FixedThreadPool)
3.定时线程池(ScheduledThreadPool )
4.单线程化线程池(SingleThreadExecutor)
5.可以窃取的线程池(WorkStealingPool)

ExecutorService threadPool = null;
threadPool = Executors.newCachedThreadPool();
//有缓冲的线程池,线程数 JVM 控制
threadPool = Executors.newFixedThreadPool(3);
//固定大小的线程池
threadPool = Executors.newScheduledThreadPool(2);
//定时线程池
threadPool = Executors.newSingleThreadExecutor();
//单线程的线程池,只有一个线程在工作
threadPool = Executors.newWorkStealingPool();
//JDK 1.8 新增,用于创建一个可以窃取的线程池,底层使用 ForkJoinPool 实现。

在这里插入图片描述

线程池的七个参数

threadPool = new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) 
//默认线程池,可控制参数比较多  

在这里插入图片描述
在这里插入图片描述
1.corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。
2.maximumPoolSize(必需):线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。
3.keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。
4.unit(必需):指定 keepAliveTime 参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
5.workQueue(必需):任务队列。通过线程池的 execute() 方法提交的 Runnable 对象将存储在该参数中。其采用阻塞队列实现。
6.threadFactory(可选):线程工厂。用于指定为线程池创建新线程的方式。
7.handler(可选):拒绝策略。当达到最大线程数时需要执行的饱和策略。

拒绝策略(四种)

RejectedExecutionHandler rejected = null;
rejected = new ThreadPoolExecutor.AbortPolicy();
//默认,队列满了丢任务抛出异常
rejected = new ThreadPoolExecutor.DiscardPolicy();
//队列满了丢任务不抛异常
rejected = new ThreadPoolExecutor.DiscardOldestPolicy();
//将最早进入队列的任务删,之后再尝试加入队列
rejected = new ThreadPoolExecutor.CallerRunsPolicy();
//如果添加到线程池失败,那么主线程会自己去执行该任务;
//如果执行程序已关闭(主线程运行结束),则会丢弃该任务

ThreadPoolExecutor.AbortPolicy:(默认)丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

举例

如果核心线程数为5,最大线程数6,任务队列数为10,现在一次提交20个任务会是一个怎样的过程?
答:首先我们得知道线程池的工作顺序为:corePoolSize -> 任务队列 -> maximumPoolSize -> 拒绝策略
.所以,第一个任务到来,创建第一个核心线程,前5个任务放到5个核心线程上;
.然后第6个任务放到队列上,也就是6至16的任务放到队列中;
.因为最大线程数为6,所以第16个任务放到创建的普通线程上;
.当第17个任务的时候,就会触发拒绝策略,策略的具体可以我们来定(1.丢任务,报异常;2.丢任务,不报异常;3.删除掉队列中的旧任务,然后加到队列中;4.添加新的线程,处理新任务,添加失败那么核心线程会去处理,如果核心线程关闭,那么,丢任务)。

标签:浅谈,队列,threadPool,任务,线程,new,ThreadPoolExecutor
来源: https://blog.csdn.net/weixin_46708745/article/details/122814412

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有