线程池原理与自定义线程池

线程池执行原理与自定义线程池

线程池执行原理:

日常记录
(一)丶使用线程池的优点:
    池化技术应用:线程池、数据库连接池、http连接池等等。

    池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。

    线程池提供了一种限制、管理资源的策略。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。

(二)丶使用线程池的好处:

    降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

    提高响应速度:当任务到达时,可以不需要等待线程创建就能立即执行。

    提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,监控和调优。

ThreadPoolExecutor:上层关系
在这里插入图片描述
执行流程:
线程池执行图:
在这里插入图片描述
线程池执行顺序:
线程池中线程,由executos()方法执行,创建线程,当线程池中常驻线程数量,无法处理,过多时,多于的请求,会被存放到堵塞队列
,当堵塞队列中,存放请求已满时,会在线程池中重新创建新线程,并且将堵塞队列,无法存放的过多请求,交由新创的线程处理
,再如果,请求数量,大于线程池中,最大线程处理数量时,那么线程将会执行拒绝策略(四种)

  1. AbortPolicy:拒绝,过多请求任务策略,并且抛出异常:RejectedExecutionException
  2. CallerRunsPolicy:将请求任务退回给,调用者
  3. DiscardOldestPolicy:抛弃队列中,等待最长的请求任务,然后把当前任务,加入队列中,排队处理
  4. DiscardPolicy:丢弃无法,处理的请求任务,不做任何处理

自定义线程池:

不使用JDK的Executors创建线程池原因:
1.FixedThreadPoolSingleThreadPool
允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM(内存溢出)
2.CachedThreadPoolScheduledThreadPool
允许创建线程数量为:Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
详细:参考阿里开发手册

线程池配置(重要

CPU密集型任务配置:即任务需要大量运算,没有大阻塞,CPU必须保证近乎全开状况
线程池最大线程配置:在CPU全开情况下,CPU核数 + 一个线程的线程池
比如八核CPU:
线程池配置:
corePoolSize:1
maximumPoolSize:8 + 1
比如8核CPU: 8 + 1 = 9个线程(最大池中线程数量)
比如:运行长时间超复杂算法的程序

IO密集型任务配置:即任务需要大量IO,即最大阻塞(但是并非一直执行任务,只是某个时刻或者时段)
IO密集型时,大部分线程都阻塞,故需要多配置线程数
配置方式一:
线程池:CPU * 2 (比如 *2,做为参考)
比如8核CPU: 8 * 2 = 16个线程(最大池中线程数量)

配置方式二:
参考公式:CPU核数 / 1 - 阻塞系数 阻塞系数:0.8 ~ 0.9 之前取值
比如8核CPU: 8 / 1 - 0.9 = 80个线程
比如:在某个时刻对数据读取的大量操作

建议具体问题具体分析
自定义线程池示范:


import java.util.concurrent.*;

/**
 * 自定义线程池:
 *   创建线程池对象:
 *     线程池基本,7个参数:
 *          1.常驻线程数量 - corePoolSize
 *          2.最大线程数量 - maximumPoolSize
 *          3.线程消亡时间 - keepAliveTime
 *          4.线程消亡时间单位 - deadTime (TimeUnit.)
 *          5.堵塞队列 - BlockingQueue<Runnable>
 *          6.拒接策略 - RejectedExecutionHandler(四种策略)
 *          7.线程工厂 - ThreadFactory
 *
 *    线程池执行流程:
 *          线程池中线程由,executos()方法执行,创建线程,当线程池中常驻线程数量,无法处理,请求时,多于的请求,会被存放到堵塞队列中
 *          ,当堵塞队列中,请求已满时,会在线程池中,重新创建线程,并且将队列,无法存放的过多请求,交由新创的线程处理
 *          ,再如果,请求数量大于,线程池中最大线程处理数量时,那么线程将会执行拒绝策略(四种)
 *      拒绝策略:
 *          AbortPolicy:拒绝,过多请求任务策略,并且抛出异常:RejectedExecutionException
 *          CallerRunsPolicy:将请求任务退回给,调用者
 *          DiscardOldestPolicy:抛弃队列中,等待最长的请求任务,然后把当前任务,加入队列中,排队处理
 *          DiscardPolicy:丢弃无法,处理的请求任务,不做任何处理
 *
 *    不使用JDK的Executors创建线程池原因:
 *      1.FixedThreadPool和SingleThreadPool:
 *          允许的请求队列长度为 Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM(内存溢出)
 *      2.CachedThreadPool和ScheduledThreadPool:
 *          允许创建线程数量为:Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
 */
public class CustomThreadPool {
    private static volatile int corePoolSize=2;//常驻线程池数量
    private static volatile int maximumPoolSize=5;//最大线程池数量
    private static volatile Long keepAliveTime=1L;//消亡时间
    private static volatile TimeUnit deadTime=TimeUnit.SECONDS;//时间单位
    private static final ArrayBlockingQueue<Runnable> arrayBlockingQueue=new ArrayBlockingQueue<>(4);//存放请求任务数量
    private static final RejectedExecutionHandler rejectedExecutionHandler=new ThreadPoolExecutor.AbortPolicy();//拒绝策略
    private static volatile ThreadFactory threadFactory = Executors.defaultThreadFactory();//创建默认线程工厂

    public static void main(String[] args) {

        //创建线程池对象
        ExecutorService executorService = new ThreadPoolExecutor(corePoolSize
                ,maximumPoolSize
                ,keepAliveTime
                ,deadTime
                ,arrayBlockingQueue
                ,threadFactory
                ,rejectedExecutionHandler);
        try {
            for (int i = 1; i <=100 ; i++) {
                executorService.execute(()->{
                    System.out.println("当前线程:"+Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //一定要释放线程
            executorService.shutdown();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值