juc之线程池

1.线程池的概述

        一种线程使用模式,线程过多会带来调度开销。进而影响缓存局部性和整体性能,而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在短时间内创建与销毁线程的代价,线程池不仅能够保证内核的充分利用,还能防止过分调度

        线程池的使用优势:线程池做的工作是控制运行中的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了核心数量,超出数量的线程排队等候,等待其他线程执行完毕,再从队列中取出任务来执行

        线程池的主要特点:

  •                 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗
  •                 提高响应速度:当任务到达时,任务可以不需要等待线程创建就能立即执行
  •                 提高线程的可管理性:线城是稀缺资源,如果无限制的创建,不仅会消耗系统资源还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
  •                 Java中的线程池是通过Executor框架实现的,该框架中用到了Executor,Executors            ExecutorService,ThreadPoolExecutor这几个类

                

                

2.线程池架构

3.线程池使用方式

        使用方式一:

 // 一池n线程   
ExecutorService executorService = Executors.newFixedThreadPool(int n);   
      

        使用方式二:

   // 一池一线程
  ExecutorService executorService1 = Executors.newSingleThreadExecutor();
   

        使用方式三:

 // 一池可扩容线程
 ExecutorService executorService2 = Executors.newCachedThreadPool();

5.线程池的七个参数

        通过查看源码发现线程池的7个参数为

                              int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

        接下来我们分别来讲讲这七个参数的作用

                corePoolSize:常驻线程池的线程数,该线程数小于最大线程数

                maximumPoolSize: 线程池中的最大线程数,该线程数大于常驻线程数

                keepAliveTime: 线程池中空闲线程等待工作的超时时间,一旦超过这个时间,该线程就                                           会被销毁

                unit: 设置超时时间

                workQueue:阻塞队列,即当线程池中的常驻线程全部在工作状态时,这时候有任务进来时,则会将这些任务放到阻塞队列,等待线程

                threadFactory: 线程工厂,创建线程的工厂

                handler:拒绝处理器,线程池有四种处理方式即AbortPolicy、DiscardPolicy、CallerRunsPolicy、DiscardOldestPolicy

6.线程池底层工作原理

        先来一张我画的图

        

        工作原理:

                                1.当我们创建了一个线程池并不意味着这个线程池里面就有了线程,当我们需要使用线程池里面的线程的时候,即开始执行execute()方法使,线程池才开始创建线程

                                2.当有任务进到这个线程池并开始寻找线程来执行任务时,首先寻找的是线程池中的corePool即上图的第一步

                                3.当corePool全部在工作,而此时又有新的任务进到线程池时,我们就需要把它们放入阻塞队列,等待其他的线程忙完再来执行他们,即上图中的第二步

                                4.当阻塞队列已满,且仍然有新的任务来到线程池寻找线程时,我们就会在线程池中新建线程,直到最大线程数即上图中的第三步

                                5.当线程池中的线程数达到了最大线程数时,且此时仍然有任务进入到线程池寻找线程,此时会触发线程池的拒绝处理策略即上图的第四步

        线程池的四种拒绝策略:

                1.AbortPolicy

                        丢弃任务并抛出RejectedExecutionException异常

                2.DiscardPolicy

                        也是丢弃任务,但是不抛出异常

                3.CallerRunsPolicy

                        由调用线程处理任务

                4.DiscardOldestPolicy

                        丢弃队列最前面的任务,然后重新尝试执行任务(重复该过程)

                                

7.自定义线程池(工作中使用的方法)(线程创建方式四)

        我们来自定义一个线程池,代码如下

        

package com.company.pool;

import java.util.concurrent.*;

// 自定义线程池
public class ThreadPoolDemo1 {
    public static void main(String[] args) {

        // 自定义一个线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                2,
                3,
                5L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.


        );
        try{
            // 从该线程池中取出线程来执行任务
            for(int i = 1;i <= 10;i++) {
                threadPoolExecutor.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "来处理业务了!!!");
                });
            }

        }catch (Exception e){
                e.printStackTrace();
            }finally {
            threadPoolExecutor.shutdown();
        }


    }
}

        

        

        

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值