目录
1. 传统线程缺点
1. 每次都需要创建和消耗线程,是需要消耗系统资源的。
2. 线程没有任务管理功能,当任务量比较大的时候没有任务队列对任务进行管理或者是拒绝任务。
因此需要使用线程池来解决上述问题。
2. 线程池是什么?
使用池化技术管理和使用线程的一种机制。是将多个线程预先存储在⼀个“池⼦”内,当有任务出现时可以避免重新创建和销毁线程所带来性能开销,只需要从“池⼦”内取出相应的线程执⾏对应的任务即可。
3. 线程池的优点
1. 复用线程,从而避免线程重复创建和销毁的性能开销。
2. 控制线程的数量,从而避免了因为线程创建过多而导致00M移除的问题。
3. 提供了任务管理的功能,从而可以实现任务缓存和任务拒绝的情况。
4. 线程池提供了更多的功能,比如定时任务。
4. 线程池的使用
线程池的创建⽅法总共有 7 种,但总体来说可分为 2 类:
1. 通过ThreadPoolExecutor手动创建线程池(有1种实现方法)
2. 使用Executors自动创建线程池(共有6中实现方法)
线程池的创建⽅式总共包含以下
7
种(其中
6
种是通过
Executors
创建的,
1
种是通过
ThreadPoolExecutor 创建的):
1.
Executors.newFixedThreadPool:创建⼀个固定⼤⼩的线程池,可控制并发的线程数,超出的线程会在队列中等待;
2.
Executors.newCachedThreadPool:创建⼀个可缓存的线程池,若线程数超过处理所需,缓存⼀段时间后会回收,若线程数不够,则新建线程;
3.
Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执⾏顺序;
4.
Executors.newScheduledThreadPool:创建⼀个可以执⾏延迟任务的线程池;
5.
Executors.newSingleThreadScheduledExecutor:创建⼀个单线程的可以执⾏延迟任务的线程
池;
6. Executors.newWorkStealingPool:创建⼀个抢占式执⾏的线程池(任务执⾏顺序不确定)。
7.
ThreadPoolExecutor:最原始的创建线程池的⽅式,它包含了
7
个参数可供设置,后⾯会详细讲。
线程池执行任务:
1. submit()
2. execut()
public class ThreadPoolDemo1 {
public static void main(String[] args) {
// 1.创建了一个包含 5 个线程的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 2.使用线程池执行任务
for (int i = 0; i < 5; i++) {
// 给线程池添加任务(使用线程池执行任务)
threadPool.submit(new Runnable() {
@Override
public void run() {
System.out.println("线程名称:" + Thread.currentThread().getName());
}
});
}
// 2.使用线程池执行任务二
for (int i = 0; i < 10; i++) {
// 给线程池添加任务
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:" + Thread.currentThread().getName());
}
});
}
}
}
输出 (顺序随机)
线程名称:pool-1-thread-1
线程名称:pool-1-thread-2
线程名称:pool-1-thread-3
线程名称:pool-1-thread-5
线程名称:pool-1-thread-4
线程的名称:pool-1-thread-2
线程的名称:pool-1-thread-4
线程的名称:pool-1-thread-5
线程的名称:pool-1-thread-3
线程的名称:pool-1-thread-1
线程的名称:pool-1-thread-3
线程的名称:pool-1-thread-5
线程的名称:pool-1-thread-4
线程的名称:pool-1-thread-2
线程的名称:pool-1-thread-1
submit VS execute:
使用submit 可以执行有返回值的任务或者是无返回值的任务;而execute只能执行不带返回值的任务。
public class ThreadPoolDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
Future<Integer> result = threadPool.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(10);
System.out.println("生成随机数:" + num);
return num;
}
});
System.out.println("得到线程池返回结果:" + result.get());
}
}
输出
生成随机数:5
得到线程池返回结果:5