本次针对http请求线程池使用介绍
线程池应用场景:1.当后台一个功能需要调用几个http接口(各个接口不相互依赖),如果不用线程池(同步请求),那么一个接一个地调用,耗时比较长,所以大部分时间花在等待接口的处理上,如果使用线程池(异步请求),那么几个http接口调用可以同时进行,并缩短了等待时间(一般中大型公司会使用到该场景,一般用户触碰到某个功能没有反应就是会影响用户体验)。2.当HTTP线程池
线程池重点:每一次http请求会创建一个线程,每次创建和销毁一个线程都需要时间,如果大量创建线程那么会让服务器资源耗尽等危险(尤其是会员活跃平台),那么线程池作用就是线程重复使用,而且必须对线程池设置超时时间(unit)
实例代码如下:
//用线程池发送请求 ExecutorService executor = Executors.newFixedThreadPool(3); //风控 FengKong fengKong = new FengKong(symptom); Thread t1 = new Thread(fengKong); executor.execute(t1); //人脸识别 FaceKnow faceKnow= new FaceKnow(facePath); Thread t2 = new Thread(faceKnow); executor.execute(t2); //身份认证 IdAuth idAuth= new IdAuth(tonguePath); Thread t3 = new Thread(idAuth); executor.execute(t3); //等待线程执行完毕,每一个task都发送了请求并获取结果解析后放到task中的某个变量中,执行完后就可以获得这些变量来获得所要的结果 executor.shutdown(); while(!executor.isTerminated()) { }
如果返回每个线程池处理的数据,要使用Callable、Future的两种使用方式 参考如下:
https://blog.csdn.net/zhaominpro/article/details/78054046 也可以参考自己的文章 https://blog.csdn.net/qq_39291929/article/details/81258857
常用几种线程池介绍
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(1).newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程
//为了体验到复用线程效果,每一个线程进行100毫秒*n休眠
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
final int index = i;
try {
Thread.sleep(index * 100);
} catch (Exception e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(index+"当前线程"+Thread.currentThread().getName());
}
});
}
}
结果如下:
0当前线程pool-1-thread-1
1当前线程pool-1-thread-1
2当前线程pool-1-thread-1
3当前线程pool-1-thread-1
4当前线程pool-1-thread-1
5当前线程pool-1-thread-1
6当前线程pool-1-thread-1
7当前线程pool-1-thread-1
8当前线程pool-1-thread-1
9当前线程pool-1-thread-1
(2). newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
线程池中设置数量为3个,那么只会有三个线程执行10条数据
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
Thread.sleep(2000);
System.out.println(index+"当前线程"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
结果如下:
0当前线程pool-1-thread-1
1当前线程pool-1-thread-2
2当前线程pool-1-thread-3
3当前线程pool-1-thread-1
4当前线程pool-1-thread-2
5当前线程pool-1-thread-3
6当前线程pool-1-thread-1
7当前线程pool-1-thread-2
8当前线程pool-1-thread-3
9当前线程pool-1-thread-1
(3).newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行
线程池延迟3秒后执行
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println("延迟3秒后执行");
}
}, 3, TimeUnit.SECONDS);
(4).newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
下面是按照顺序执行FIFO(一般情况下多线程index是乱的,该线程池保证了按照顺序执行)
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
public void run() {
try {
System.out.println("--index--"+index);
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
结果如下:
--index--0
--index--1
--index--2
--index--3
--index--4
--index--5
--index--6
--index--7
--index--8
--index--9