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自带的四种线程池相关推荐

  1. Java通过Executors提供四种线程池

    http://cuisuqiang.iteye.com/blog/2019372 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如 ...

  2. Java中常用的四种线程池

    在Java中使用线程池,可以用ThreadPoolExecutor的构造函数直接创建出线程池实例,在Executors类中,为我们提供了常用线程池的创建方法. ​ 接下来我们就来了解常用的四种: ne ...

  3. Java四种线程池的使用 1

    Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFi ...

  4. java中executors_Java通过Executors提供四种线程池

    http://cuisuqiang.iteye.com/blog/2019372 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如 ...

  5. Java ExecutorService四种线程池的例子与说明

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() {@Overridepublic void run() {// ...

  6. Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor...

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() {@Override public void run ...

  7. [转]new Thread的弊端及Java四种线程池的使用

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new ...

  8. Java 四种线程池的用法分析

    1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() {@Overridepublic void run() {// ...

  9. Java 四种线程池

    原文 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下n ...

最新文章

  1. keras 的 example 文件 imdb_fasttext.py 解析
  2. Spring(07)——单例注入多例之lookup-method
  3. 代码块练习题:看代码写程序的执行结果。
  4. sumif三个条件怎么填_Excel条件求和函数sumif详解及应用
  5. 分析引擎 2.0 已来,神策再刷行业标准!
  6. Ubuntu18.04安装Nautilus-actions自定义文件管理器鼠标右键列表
  7. select函数_SQL高级功能:窗口函数
  8. Session【常见问题请见下图】
  9. POJ 2996, Help Me with the Game
  10. 放弃大厂高薪的程序员,涌进体制内
  11. Markdown的使用心得
  12. abaqus Isight学习
  13. 2.1 软件开发生命周期模型
  14. 转载 GIS的下个十年(Cary Mann, vice president, Bentley)
  15. iOS 最新 APP提交上架流程~(打包 ipa)
  16. 期货反跟单-侃侃人工反跟单那些事儿
  17. 华为新员工入职培训计划曝光!你留不住员工的原因就在这! zz
  18. 《Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks》论文翻译
  19. 在线CAD图纸批注功能方案比较与实现
  20. 当双绞线遇上光纤布线-NETLINK多模光纤收发器HTB-1100

热门文章

  1. realme真我gt能升级鸿蒙系统吗,realme真我GT Neo专为学生党打造,堪称性价比之王...
  2. Linux设备驱动程序-并发和竞态
  3. 华为畅享9,进入小程序,经常加载不出详情页 editorCtx 富文本
  4. ROS运行程序让小海龟实现圆周运动
  5. windows 10设置host
  6. 最简单的VMware中Linux联网的一种方法
  7. XP系统开机蓝屏四步解决【装机吧】
  8. LeNet5论文解读
  9. 解决qemu-system-aarch64 Guest has not initialized the display (yet)
  10. matlab 跳转到函数,matlab中fmincon函数如何调用??