java自带的四种线程池
java预定义的哪四种线程池?
- newSingleThreadExexcutor:单线程数的线程池(核心线程数=最大线程数=1)
- newFixedThreadPool:固定线程数的线程池(核心线程数=最大线程数=自定义)
- newCacheThreadPool:可缓存的线程池(核心线程数=0,最大线程数=Integer.MAX_VALUE)
- newScheduledThreadPool:支持定时或周期任务的线程池(核心线程数=自定义,最大线程数=Integer.MAX_VALUE)
四种线程池有什么区别?
上面四种线程池类都继承ThreadPoolExecutor,在创建时都是直接返回new ThreadPoolExecutor(参数),它们的区别是定义的ThreadPoolExecutor(参数)中参数不同,而ThreadPoolExecutor又继承ExecutorService接口类
- newFixedThreadPool
定义: ExecutorService executorService=Executors.newFixedThreadPool(2);
缺点:使用了LinkBlockQueue的链表型阻塞队列,当任务的堆积速度大于处理速度时,容易堆积任务而导致OOM内存溢出
- newSingleThreadExecutor
定义:ExecutorService executorService =Executors.newSingleThreadExecutor();
上面代码神似new FixedThreadPoop(1),但又有区别,因为外面多了一层FinalizableDelegatedExecutorService,其作用:
可知,fixedExecutorService的本质是ThreadPoolExecutor,所以fixedExecutorService可以强转成ThreadPoolExecutor,但singleExecutorService与ThreadPoolExecutor无任何关系,所以强转失败,故newSingleThreadExecutor()被创建后,无法再修改其线程池参数,真正地做到single单个线程。
缺点:使用了LinkBlockQueue的链表型阻塞队列,当任务的堆积速度大于处理速度时,容易堆积任务而导致OOM内存溢出
- newCacheThreadPool
定义:ExecutorService executorService=Executors.newCacheThreadPool();
缺点:SynchronousQueue是BlockingQueue的一种实现,它也是一个队列,因为最大线程数为Integer.MAX_VALUE,所有当线程过多时容易OOM内存溢出
- ScheduledThreadPool
定义:ExecutorService executorService=Executors.newScheduledThreadPool(2);
源码: public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {//ScheduledThreadPoolExecutor继承ThreadPoolExecutorreturn new ScheduledThreadPoolExecutor(corePoolSize);}public ScheduledThreadPoolExecutor(int corePoolSize) {//ScheduledThreadPoolExecutor继承ThreadPoolExecutor,故super()会调用ThreadPoolExecutor的构造函数初始化并返回一个ThreadPoolExecutor,而ThreadPoolExecutor使实现ExecutorService接口的//最终ScheduledThreadPoolExecutor也和上面几种线程池一样返回的是ExecutorService接口的实现类ThreadPoolExecutorsuper(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue()); }
线程池有哪几个重要参数?
ThreadPoolExecutor构造方法如下:
- keepAliveTime是指当前线程数位于 [核心线程数,最大线程数] 之间的这些非核心线程等待多久空闲时间而没有活干时,就退出线程池;
- 等待丢列的大小与最大线程数是没有任何关系的,线程创建优先级=核心线程 > 阻塞队列 > 扩容的线程(当前核心线程数小于最大线程数时才能扩容线程)
- 假如核心线程数5,等待队列长度为3,最大线程数10:当线程数不断在增加时,先创建5个核心线程,核心线程数满了再把线程丢进等待丢列,等待队列满了(3个线程),此时会比较最大线程数(只有等待丢列满了最大线程数才能出场),还可以继续创建2个线程(5+3+2),若线程数超过了最大线程数,则执行拒绝策略;
- 假如核心线程数5,等待队列长度为3,最大线程数7:当线程数不断在增加时,先创建5个核心线程,核心线程数满了再把线程丢进等待丢列,当等待队列中有2个线程时达到了最大线程数(5+2=7),但是等待丢列还没满所以不用管最大线程数,直到等待丢列满了(3个阻塞线程),此时会比较最大线程数(只有等待丢列满了最大线程数才能出场),此时核心+等待丢列=5+3=8>7=最大线程数,即已经达到最大线程数了,则执行拒绝策略;
- 如果把等待丢列设置为LinkedBlockingQueue无界丢列,这个丢列是无限大的,就永远不会走到判断最大线程数那一步了
如何自定义线程池
可以使用有界队列,自定义线程创建工厂ThreadFactory和拒绝策略handler来自定义线程池
public class ThreadTest {public static void main(String[] args) throws InterruptedException, IOException {int corePoolSize = 2;int maximumPoolSize = 4;long keepAliveTime = 10;TimeUnit unit = TimeUnit.SECONDS;BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);ThreadFactory threadFactory = new NameTreadFactory();RejectedExecutionHandler handler = new MyIgnorePolicy();ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,workQueue, threadFactory, handler);executor.prestartAllCoreThreads(); // 预启动所有核心线程 for (int i = 1; i <= 10; i++) {MyTask task = new MyTask(String.valueOf(i));executor.execute(task);}System.in.read(); //阻塞主线程}static class NameTreadFactory implements ThreadFactory {private final AtomicInteger mThreadNum = new AtomicInteger(1);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, "my-thread-" + mThreadNum.getAndIncrement());System.out.println(t.getName() + " has been created");return t;}}public static class MyIgnorePolicy implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor e) {doLog(r, e);}private void doLog(Runnable r, ThreadPoolExecutor e) {// 可做日志记录等System.err.println( r.toString() + " rejected"); // System.out.println("completedTaskCount: " + e.getCompletedTaskCount());}}static class MyTask implements Runnable {private String name;public MyTask(String name) {this.name = name;}@Overridepublic void run() {try {System.out.println(this.toString() + " is running!");Thread.sleep(3000); //让任务执行慢点} catch (InterruptedException e) {e.printStackTrace();}}public String getName() {return name;}@Overridepublic String toString() {return "MyTask [name=" + name + "]";}} }
运行结果:
其中7-10号线程被拒绝策略拒绝了,1、2号线程执行完后,3、6号线程进入核心线程池执行,此时4、5号线程在任务队列等待执行,3、6线程执行完再通知4、5线程执行
java自带的四种线程池相关推荐
- Java通过Executors提供四种线程池
http://cuisuqiang.iteye.com/blog/2019372 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如 ...
- Java中常用的四种线程池
在Java中使用线程池,可以用ThreadPoolExecutor的构造函数直接创建出线程池实例,在Executors类中,为我们提供了常用线程池的创建方法. 接下来我们就来了解常用的四种: ne ...
- Java四种线程池的使用 1
Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFi ...
- java中executors_Java通过Executors提供四种线程池
http://cuisuqiang.iteye.com/blog/2019372 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如 ...
- Java ExecutorService四种线程池的例子与说明
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() {@Overridepublic void run() {// ...
- Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor...
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() {@Override public void run ...
- [转]new Thread的弊端及Java四种线程池的使用
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new ...
- Java 四种线程池的用法分析
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() {@Overridepublic void run() {// ...
- Java 四种线程池
原文 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下n ...
最新文章
- keras 的 example 文件 imdb_fasttext.py 解析
- Spring(07)——单例注入多例之lookup-method
- 代码块练习题:看代码写程序的执行结果。
- sumif三个条件怎么填_Excel条件求和函数sumif详解及应用
- 分析引擎 2.0 已来,神策再刷行业标准!
- Ubuntu18.04安装Nautilus-actions自定义文件管理器鼠标右键列表
- select函数_SQL高级功能:窗口函数
- Session【常见问题请见下图】
- POJ 2996, Help Me with the Game
- 放弃大厂高薪的程序员,涌进体制内
- Markdown的使用心得
- abaqus Isight学习
- 2.1 软件开发生命周期模型
- 转载 GIS的下个十年(Cary Mann, vice president, Bentley)
- iOS 最新 APP提交上架流程~(打包 ipa)
- 期货反跟单-侃侃人工反跟单那些事儿
- 华为新员工入职培训计划曝光!你留不住员工的原因就在这! zz
- 《Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks》论文翻译
- 在线CAD图纸批注功能方案比较与实现
- 当双绞线遇上光纤布线-NETLINK多模光纤收发器HTB-1100
热门文章
- realme真我gt能升级鸿蒙系统吗,realme真我GT Neo专为学生党打造,堪称性价比之王...
- Linux设备驱动程序-并发和竞态
- 华为畅享9,进入小程序,经常加载不出详情页 editorCtx 富文本
- ROS运行程序让小海龟实现圆周运动
- windows 10设置host
- 最简单的VMware中Linux联网的一种方法
- XP系统开机蓝屏四步解决【装机吧】
- LeNet5论文解读
- 解决qemu-system-aarch64 Guest has not initialized the display (yet)
- matlab 跳转到函数,matlab中fmincon函数如何调用??