引言
合理利用线程池能够带来三个好处。
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
- 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
多线程编程基础
- Java基础
- 线程基本概念
- 创建线程的方式
- 实现同步锁的方式
参考书籍:《Java并发编程核心技术》->基础、《Java并发编程实战》
J.U.C基本概念及源码解析
深入理解Java线程池:ThreadPoolExecutor
创建使用ThreadPoolExecutor
虽然Javadocs推荐我们使用Executors利用工厂模式向我们提供的4种线程池实现方式,但是在阿里编码规约里并不推荐使用,原因是使用Executors创建线程池不会传入这个参数而使用默认值所以我们常常忽略这一参数,而且默认使用的参数会导致资源浪费,不可取。
【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,
这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
ExecutorTest.Java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package com.pace2car;
import java.util.concurrent.*;
/**
* @author Pace2Car
* @date 2019/1/8 15:21
*/
public class ExecutorTest {
public static void main(String[] args) throws InterruptedException {
ThreadFactory namedThreadFactory = Executors.defaultThreadFactory();
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 200,
TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5),
namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
for (int i = 0; i < 10; i++) {
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行完毕的任务数目:"+executor.getCompletedTaskCount());
}
executor.shutdown();
Thread.sleep(5000);
System.out.println("线程池中线程数目:"+executor.getPoolSize()+",队列中等待执行的任务数目:"+
executor.getQueue().size()+",已执行完毕的任务数目:"+executor.getCompletedTaskCount());
}
}
MyTask.Java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package com.pace2car;
/**
* @author Pace2Car
* @date 2019/1/8 15:27
*/
public class MyTask implements Runnable {
private int taskNum;
public MyTask(int num) {
this.taskNum = num;
}
public void run() {
System.out.println("正在执行task "+taskNum);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task "+taskNum+"执行完毕");
}
}