今天我们来聊聊,面试常问的线程池,首先在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这个创建线程的方法 ;
首先解释一下这个歌方法里面的参数都是什么意思
| 参数含义 |
| 核心线程数 |
| 最大线程数 |
| 空闲线程等待释放时间 |
| 时间单位 |
| 等待阻塞队列 |
| 线程工厂 |
| 拒绝策略 |
现在我们先写一段代码,模拟一下 用线程池去处理请求的过程
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个请求时没有处理,并且抛了一个异常,那为啥会抛异常,原因就是我们上面设置了拒绝策略
策略 | 含义 |
| |
| 任务从哪里来回到哪里去 |
| 当线程池满,丢掉任务,不会抛出异常 |
| 单线程池满,会尝试去和最早获得线程任务的去竞争,不会抛出异常 |
这些策略字面上很好解释我就不用画图了,
,现在还有一个参数,keepAliveTime,这就是说,现在线程池里面有3个线程,现在任务都执行完,现在就回先处于等待装,如果超过这个世界阈值就会释放线程资源,
好了今天就这些,关于线程池你学废了吗?