• Java 多线程进阶-并发编程(二) Executor Framework(JDK5以上)


    • Executor(1)

      • 从JDK5 开始提供Executor FrameWork(java.util.concurrent.*)
        • 分离任务和创建和执行者的创建
        • 线程重复利用(new线程代价很大)
      • 理解共享线程池的概念
        • 预设好的多个Thread, 可弹性增加
        • 多次执行很多很小的任务
        • 任务创建和执行过程解耦
        • 程序猿无需关心线程池执行任务过程
    • 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;
                }
            }
        
    • 总结

      • 掌握共享线程池原理
      • 熟悉 Executor框架, 提高多线程执行效率
  • 相关阅读:
    homework2
    一件关于Bug的小事
    软件测试作业三:有关控制流图、覆盖内容
    用CSS改变select框的样式
    lab1--ideal + junit
    软件测试作业二
    记一次曾经项目中遇到的错误
    02组_现代软件工程_第04次作业——利用4象限原理分析自身CanTool项目的构成
    02组_现代软件工程_第03次作业——对于自身评价(原有水平以及长远目标分析总结)
    02组_现代软件工程_第02次作业——初谈GitHub使用详解以及设计
  • 原文地址:https://www.cnblogs.com/sweetXiaoma/p/12725902.html
Copyright © 2020-2023  润新知