简介
工作原理
如何获取线程池对象
构造器的参数含义
注意事项
构造器-ThreadPoolExecutor
// ArrayBlockingQueue 是一个有界的阻塞队列,它的内部实现是一个数组。有界的意思是它的容量是有限的,我们必须在创建 ArrayBlockingQueue 实例的时候指定容量大小。
// Executors.defaultThreadFactory() 是一个线程工厂,它的作用是创建一个新的线程。这个线程工厂创建的线程都是普通优先级、非守护、正常终止的线程。
// ThreadPoolExecutor.AbortPolicy() 是拒绝策略,当线程池中的线程数量达到最大线程数并且阻塞队列已满的情况下,新提交的任务会被拒绝,并抛出 RejectedExecutionException 异常。
ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
线程池处理Runnable任务
常用API
代码实现
ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
// 当任务的实际数量> 核心线程 + 阻塞队列的容量时,会创建临时线程 8 > 3 + 4
// 当任务的实际数量 > 最大线程数 + 阻塞队列的容量时,会抛出异常 10 > 5 + 4
for (int i = 0; i < 8; i++) {
//提交任务
pool.execute(myRunnable);
}
//关闭线程池 很少使用,尽量不用,我们应该保持线程池的长期运行,除非我们确定不再需要线程池。
pool.shutdown();
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
临时线程的创建时机
- 当任务的实际数量> 核心线程 + 阻塞队列的容量时,会创建临时线程 8 > 3 + 4
- 当任务的实际数量 > 最大线程数 + 阻塞队列的容量时,会抛出异常 10 > 5 + 4
新任务的拒绝策略
线程池调用Callable
比较
- 调用Runnable使用的execute方法
- 调用Callable使用的是submit方法
代码实现
// 创建线程池
ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
//创建Callable任务
MyCallable myCallable = new MyCallable();
for (int i = 0; i < 8; i++) {
//提交任务
Future<String> future = pool.submit(myCallable);
try {
//获取任务执行结果
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + " is running");
Thread.sleep(1000);
return "success";
}
}
使用工具类创建线程池Excutors
创建API
##代码
// 创建线程池
ExecutorService pool = Executors.newFixedThreadPool(5);
//创建Callable任务
MyCallable myCallable = new MyCallable();
for (int i = 0; i < 8; i++) {
//提交任务
Future<String> future = pool.submit(myCallable);
try {
//获取任务执行结果
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
核心线程数量
- 计算密集型任务:大部分时间是计算机使用cpu进行计算
- IO密集型任务:大部分时间是IO流输入输出
- 计算密集型任务:核心线程数量 = CPU + 1
- IO密集型任务:核心线程数量 = CPU * 2