面试热点问题??其实线程池,也就那回事

今天我们来聊聊,面试常问的线程池,首先在java中创建线程池一般是采用都是采用ExecutorService 子类去创建线程,

我们先来看看创建线程池有那几种方法;

       方法一,采用Executors下面的今天方法区创建线程(这种在公司中并不常用)

不通过我们分析,其实这个Execuators类里面创建线程也就是掉用了ThreadPoolExecutor 这个方法

  public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }

这也是公司里面开发常用的创建线程池的方式了.

我们今天主要就是讲下这个ThreadPoolExecuTor这个创建线程的方法 ;

首先解释一下这个歌方法里面的参数都是什么意思

ThreadPoolExecuTor参数详见
参数名
参数含义
corePoolSize
核心线程数
maximumPoolSize
最大线程数
keepAliveTime
空闲线程等待释放时间
TimeUnit
时间单位
BlockingQueue<Runnable>
等待阻塞队列
ThreadFactory
线程工厂
RejectedExecutionHandler
拒绝策略

现在我们先写一段代码,模拟一下 用线程池去处理请求的过程

public class demo {

    static class Http{
        String  request="request";
        String  response="response";

        public Http(int i) {
            this.request = request+i;
            this.response = response+i;
        }
    }

    public static void main(String[] args) {
        //创建线程池
        ExecutorService  httpHandlerThreadPool=new ThreadPoolExecutor(
                2,     //核心线程数
                7, //最大线程数
                3,    //空闲线程存活时间
                TimeUnit.SECONDS,   //存活时间单位
                new LinkedBlockingDeque<>(3),//阻塞队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy() //阻塞策略  : 如果线程池以满 ,丢弃任务并且抛出异常

        );

        ArrayList<Http> HttpList=new ArrayList<>();
        //模拟2 http请求
        for (int i = 1; i <=6; i++) {
            HttpList.add(new Http(i));
        }
        //使用线程池模拟处理请求
        for (Http http : HttpList) {
            //
            httpHandlerThreadPool.execute(()->{
                //处理业务
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println( Thread.currentThread().getName()+ "线程处理:  "+http.request+"响应:"+http.response);

            });
        }
        httpHandlerThreadPool.shutdown();
    }

}

看下一下执行结果

给大家画一个图,模拟线程处理请求

我们设置的颗核心线程数是2,我们可以看到执行结果,是有两个线程去处理了我们的请求,跟我上面图画的一样,那么当我们线程数大于,我们的

核心线程数时会发生什么呢。

此们把请求数设置到5

   //模拟5 http请求
        for (int i = 1; i <=5; i++) {
            HttpList.add(new Http(i));
        }

我们看下结果

我们可以看到结果里面还是只有2个线程去执行。当我们的线程池中,工作线程数大于核心线程数时,接下的请求会·就会去到阻塞队列等待,不会创建新的线程

那么如果队列满了以后,再加入新的请求时会怎么样,这次我们发7个请求看一下

   //模拟7 http请求
        for (int i = 1; i <=7; i++) {
            HttpList.add(new Http(i));
        }

看一下执行结果:

 

此时我们可以清楚的看到线程池中有4个线程去处理我们的请求,

和我画的图基本一致,那么问题来了,如果说,此时线程池中工作线程数>大于最大线程数时,会是怎么样的结果呢?

我们加到11个请求看看结果如何

 ArrayList<Http> HttpList=new ArrayList<>();
        //模拟11 http请求
        for (int i = 1; i <=11; i++) {
            HttpList.add(new Http(i));
        }

结果图:

 我们可以看到到第11个请求时没有处理,并且抛了一个异常,那为啥会抛异常,原因就是我们上面设置了拒绝策略

 

策略含义
 
ThreadPoolExecutor.AbortPolicy() 
 如果线程池以满 ,丢弃任务并且抛出异常
ThreadPoolExecutor.CallerRunsPolicy()
任务从哪里来回到哪里去
ThreadPoolExecutor.DiscardPolicy() 
当线程池满,丢掉任务,不会抛出异常
ThreadPoolExecutor.DiscardOldestPolicy()
单线程池满,会尝试去和最早获得线程任务的去竞争,不会抛出异常

这些策略字面上很好解释我就不用画图了,

,现在还有一个参数,keepAliveTime,这就是说,现在线程池里面有3个线程,现在任务都执行完,现在就回先处于等待装,如果超过这个世界阈值就会释放线程资源,

好了今天就这些,关于线程池你学废了吗?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值