首页 > 其他分享 >线程池ThreadPoolExecutor

线程池ThreadPoolExecutor

时间:2022-12-11 23:57:38浏览次数:72  
标签:队列 创建 任务 线程 new ThreadPoolExecutor

回顾Java创建线程的几种方式

1,继承Thread(实际Thread也是实现Runnable接口);

2,实现Runnable接口;

3,实现Callable接口(返回值);

4,由线程池创建。

 

根据阿里巴巴Java开发手册,关于并发编程有两个强制要求:

1.线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。

2.线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,规避资源耗尽风险。

解释:

第1点好理解,线程的创建,挂起,唤醒都会引起线程内核态和用户态的切换,频繁的创建会导致“过度切换”问题。

第2点,先来看看Executors创建线程池的方式:

 

newFixedThreadPool

 newSingleThreadExecutor

newFixedThreadPool和newSingleThreadExecutor的核心线程数和最大线程数都是(传参)常量,但是它们的等待队列都用了LinkedBlockingQueue,

这是一个线程安全的单向链表队列,但是队列长度就趋于无界(也有人叫无界队列)。实际应用中很可能会造成任务积压,进而导致OOM。

 

newCachedThreadPool

 newScheduledThreadPool

newCachedThreadPool和newScheduledThreadPool就更加直观,允许的最大线程数为Int的最大值,生产中可能会因创建大量线程导致OOM。

故阿里巴巴强制不允许使用Executors创建线程池。

另外,这四种通过Executors创建线程池的方式,底层都是通过new ThreadPoolExecutor(...)的方式,故而,

推荐,直接使用new ThreadPoolExecutor()的方式创建线程池,或者继承ThreadPoolExecutor类来自定义线程池。

比如github有名的hippo4j项目,ExtensibleThreadPoolExecutor

 

 就是通过继承ThreadPoolExecutor的方式,自定义线程池。

 

ThreadPoolExecutor的使用

 创建线程池:

/**
         * 1 核心线程数
         * 2 最大线程数
         * 3 非核心线程空闲时的存活时间
         * 4 时间单位
         * 5 阻塞队列
         * 6 线程工厂
         * 7 拒绝策略
         **/
        ExecutorService es = new ThreadPoolExecutor(10, 50,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>(), new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread();
                t.setName("ceshi1");
                return t;
            }
        }, new ThreadPoolExecutor.AbortPolicy());

线程池的5种状态:

 

状态说明:

RUNNING:能够接收新任务以及完成现有任务

SHUTDOWN:不接收新任务,但会继续处理现有任务(包括正在进行的任务和阻塞队列中的任务)

STOP:严重,不接收新任务,现有任务也会中断(也包括丢弃阻塞队列中的任务)

TIDYING:线程池即将被销毁的中间状态

TERMINATED:线程池彻底终止。

 

ThreadPoolExecutor的原理

 

线程复用原理

 

 通过while循环不停的从阻塞队列中获取任务来执行,线程和任务已解耦,

 

何时将设定的核心线程数建满?

假设我们的主代码在并发环境下,会有超过2个以上的并发请求在调用execute,

 对于每一个请求,都会通过addWorker方法创建一个线程,直到总的线程数达到核心线程数为止。

 corePoolSize用volatile修饰,对多线程是可见的。

比如创建了10个核心线程的线程池,需要通过并发工具来模拟这个情况,否则单机模拟不出这个情况。

标签:队列,创建,任务,线程,new,ThreadPoolExecutor
From: https://www.cnblogs.com/hangwei/p/16962296.html

相关文章

  • 线程概念和多线程模型
    ①知识总览②什么是线程,为什么要引入线程?可以把线程理解为“轻量级进程”线程是一个基本的CPU执行单元,也是程序执行流的最小单位。引入线程后,不仅是进程间可以并发,进......
  • Java 线程池之Jetty 线程池学习总结
    Java线程池之Jetty线程池学习总结前提Jetty11.0.x为什么是Jetty?Java提供4中创建线程池的快捷方式Executors.newFixedThreadPool();Executors.newCachedThreadPool();Exe......
  • python多进程&多线程
    python多进程&多线程1.多进程定义  2.多线程  3.应用  3.1不使用多线程则顺序执行1importlogging2fromthreadingimportThread3fromti......
  • 操作系统学习笔记-用户级线程和核心级线程
    (一)绪论1.多进程多进程并发结构,即将多个进程同时放在内存中启动执行,然后在这些进程之间来回切换交替执行,这样的结构可以让CPU的工作效率大幅提升,也提高了整个计算机硬......
  • 用户重复注册分析-多线程事务中加锁引发的bug
    本文记录博主线上项目一次用户重复注册问题的分析过程与解决方案博主github地址: github.com/wayn111一复现过程线上客户端用户使用微信扫码登陆时需要再绑定一个手......
  • 【深入分析java线程池的实现原理】
    前言线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监控,有以下好处:1、降低资源消耗;2、提高响应速......
  • python :控制线程上限,防止无限开启线程
    importthreadingsem=threading.Semaphore(10)#设置最大线程数#在线程调用的函数开始设置sem.acquire()#在线程调用的函数最后设置sem.release()defxiazai(iiv,cha......
  • 多线程练习
    Map<String,Integer>totalStock=newHashMap<>();AtomicIntegertotal=newAtomicInteger();privateList<Car>carList=newArrayList<>();publ......
  • cpu放弃线程的时机
    ......
  • [python] ThreadPoolExecutor线程池
    初识Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中......