-
Executor(1)
- 从JDK5 开始提供Executor FrameWork(java.util.concurrent.*)
- 分离任务和创建和执行者的创建
- 线程重复利用(new线程代价很大)
- 理解共享线程池的概念
- 预设好的多个Thread, 可弹性增加
- 多次执行很多很小的任务
- 任务创建和执行过程解耦
- 程序猿无需关心线程池执行任务过程
- 从JDK5 开始提供Executor FrameWork(java.util.concurrent.*)
-
Executor(2)
- 主要类: ExecutorService, ThreadPoolExecutor, Future
- Executors.newCachesThreadPool/newFixedThreadPool 创建线程池
- ExecutorService 线程池服务
- Callable 具体的逻辑对象(线程类),
Callable 和 Runnable 是等价的, 可以用来执行一个任务.
Runnable 的 run 方法没有返回值;
Callable 的 call 方法可以有返回值. - Future 返回结果
- 示例代码
package thread0411; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.*; /** * 分多个线程, 分段计算两个数字之间累加的和. * 1-1000的和 = 1-100的和 + 101-200的和 + ... */ public class ThreadPool_Executor2 { public static void main(String[] args) { long m = 1; long n = 1000; //100000000 // 执行线程池 ThreadPoolExecutor exec = (ThreadPoolExecutor) Executors.newFixedThreadPool(4); List<Future<Integer>> resultList = new ArrayList<>(); // 统计 1-1000 的总和, 分成10个任务去计算, 提交任务 long section = n / 10; for (int i = 0; i < 10; i++) { SumTask111 calc = new SumTask111(i * section + 1, (i + 1) * section); Future<Integer> re = exec.submit(calc); resultList.add(re); } // 每隔50毫秒, 轮询查询一下是否全部完成. // 等待10个任务结束 do { System.out.printf(LocalDateTime.now() + " => " + "Main: 已经完成任务个数: %d" + " ", exec.getCompletedTaskCount()); // for (int i = 0; i < resultList.size(); i++) { // 输出一下任务是否完成 // Future<Integer> re = resultList.get(i); // System.out.printf(LocalDateTime.now() + " => " + "Main: Task %d: %s" + " ", i, re.isDone()); // } try { Thread.sleep(50); // 过 50ms 再检查一下是否全部完成. } catch (InterruptedException e) { e.printStackTrace(); } } while (exec.getCompletedTaskCount() < resultList.size()); // 所有任务都已经结束了, 综合计算结果 int total = 0; for (Future<Integer> result : resultList) { Integer sum; try { sum = result.get(); total += sum; } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } System.out.printf(LocalDateTime.now() + " => " + "%d-%d的总和 = %d" + " ", m, n, total); } } class SumTask111 implements Callable<Integer> { // 定义该线程中的计算和的开始 结束 private long startNumber, endNumber; public SumTask111(long startNumber, long endNumber) { this.startNumber = startNumber; this.endNumber = endNumber; } @Override public Integer call() throws Exception { int sum = 0; for (long i = startNumber; i <= endNumber; i++) { sum += i; } Thread.sleep(new Random().nextInt(1000)); System.out.printf(LocalDateTime.now() + " => SumTask111 call() %s: %d ", Thread.currentThread().getName(), sum); return sum; } }
- 主要类: ExecutorService, ThreadPoolExecutor, Future
-
总结
- 掌握共享线程池原理
- 熟悉 Executor框架, 提高多线程执行效率