线程池详解

1.线程池的引用:

       为了提高效率,基于之前的知识:由于进程的创建与销毁所消耗的资源过多,我们便引入了线程,所以如果还想提高效率的话,就需要引入更轻量级的线程------->(协程/纤程),但是这种更加轻量级的线程并没有引入Java的标准库中,所以我们引用不了,所以我们便有了第二种提高效率的方式------>线程池

使用线程池可以降低创建/销毁线程的开销,那么为什么可以降低开销呢?

  • 我们事先就可以要使用的线程放到池中,后续可以直接在池中获取,使用完了便还给池
  • 从池子中获取/归还线程,是我们用户态可以直接通过代码实现的,并不需要内核态

2.线程池接口类关系图

3.库中定义好的线程池:

           在这我们不难看出,线程池对象并不是以我们以前的方式new出来的,而是使用Executors类下的静态方法引出的,而这种方式我们称之为工厂模式,简单解释即为,使用静态方法来替代构造方法来创建对象,其优势就在于当创建很多类型不同的对象时更好地区分明了

        //固定池  固定了10个线程
        ExecutorService pool1 = Executors.newFixedThreadPool(10);
        //缓存池 线程数量是动态变化的  任务多了就多几个
        ExecutorService pool2 = Executors.newCachedThreadPool();
        //类似于定时器
        ExecutorService pool3 = Executors.newScheduledThreadPool(3);
        //单个线程
        ExecutorService pool4 = Executors.newSingleThreadExecutor();

        

4.自定义线程池:

        //核心线程数
        int coreSize = 1;
        //最大线程数
        int maximum = 3;
        //线程存活时间
        long keepAlive = 10;
        //线程存活时间单位
        TimeUnit unit = TimeUnit.SECONDS;
        //阻塞队列
        BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue(3);
        //线程工厂
        ThreadFactory factory = Executors.defaultThreadFactory();
        //拒绝策略
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        
        ExecutorService myPool = new ThreadPoolExecutor(coreSize,maximum,keepAlive,unit,blockingQueue,factory,handler);

参数解释

        核心线程数:类似于公司里的正式员工,可以偶尔的摸鱼

        最大线程数:最大线程数 - 核心线程数 = 实习员工   实习员工如果摸鱼,就会被开除

        线程存活时间:实习员工摸鱼的最大时间

        时间单位 : 定义摸鱼时间的单位的

        阻塞队列: 带有阻塞功能存放任务的队列

        线程工厂:用于创建线程的

        拒绝策略:描述了当线程池任务满了后,继续添加任务会有什么行为

5.四种拒绝策略

  • AbortPolicy:默认拒绝策略,拒绝任务,抛出异常
        static class myTask implements Runnable{
                private int i ;
                public myTask(int i){
                    this.i = i;
                }
    
                @Override
                public void run() {
                    try {
                        //为什么这里要休眠一下才能出现效果:保证每个线程只执行一个任务
                        //如果不休眠 可能执行的太快了 一个线程会执行几个任务 那么就看不到效果
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("执行任务:"+i);
                }
            }
    
    
                //核心线程数
                int coreThread = 1;
    
                //最大线程数
                int maxThread = 3;
    
                //存和时间
                long keepAlivetime = 1;
    
                //存活时间单位
                TimeUnit unit = TimeUnit.SECONDS;
    
                //阻塞队列
                BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2);
    
                //线程工程
                ThreadFactory factory = Executors.defaultThreadFactory();
                
                //拒绝策略
                RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
    
                ThreadPoolExecutor poolExecutor = new                                
           ThreadPoolExecutor(coreThread,maxThread,keepAlivetime,unit,queue,factory,handler);
    
                //最大任务数 = 最大线程数 + 阻塞队列数 3+2
                for(int i = 1; i <= 10; i++){
                    try{
                        //也可以使用submit方法  excuete是
                        poolExecutor.execute(new myTask(i));
                    }catch (Exception e){
                        System.out.println("任务:"+i + e.getMessage());
                    }
                }

  •     CallerRunsPolicy:会自动添加多的线程来执行新添的任务

        

  • DiscardPolicy:拒绝任务,不报错       

 

  • DiscardOldestPolicy:丢弃阻塞队列中最老的任务,添加任务
    //4.DiscardOldestPolicy  任务新增  丢弃阻塞队列中最老的任务  添加到阻塞队列中
    //其顺序为: 核心线程数----->阻塞队列------>最大线程数
    //1.(核心线程  2.(阻塞队列  3.(阻塞队列 4.(最大线程 5.(最大线程 6.(舍弃2 进入阻塞队列  
    //7.(舍弃3 进入阻塞队列  8.(舍弃6 进入阻塞队列   9.(舍弃7 进入阻塞队列  
    //10.(舍弃8 进入阻塞队列
    //故最后执行的任务有 1 4 5 9 10

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值