当前位置:   article > 正文

Java实战-- 线程池及lambda_new threadpoolexecutor()案例 lamda

new threadpoolexecutor()案例 lamda

线程池

SpringBoot + 线程池 使用

    • 自定义线程池
      • 定义一个线程池配置类
          1. @Configurable
          2. @EnableAsync //开启线程池,应用启动时开启
          3. public class ThreadPoolConfig {
          4. @Bean("taskExecutor")
          5. public Executor asyncServiceExecutor(){
          6. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
          7. //设置核心线程数:线程池创建时初始化的线程数
          8. executor.setCorePoolSize(5);
          9. //设置最大线程数:只有在缓冲队列满了之后才会申请超过核心线程数的线程
          10. executor.setMaxPoolSize(20);
          11. //配置队列大小:用来缓冲执行任务的队列
          12. executor.setQueueCapacity(500);
          13. //设置线程空闲时间(秒):当超过了核心线程之外的线程在空闲时间达到后会被销毁
          14. executor.setKeepAliveSeconds(60);
          15. //设置线程池的前缀:方便我们定位处理任务所在的线程池
          16. executor.setThreadNamePrefix("thread-pool-task");
          17. //缓冲队列满了之后的拒绝策略:由 调用线程处理(一般是主线程)
          18. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
          19. //等待所有任务结束后再关闭线程池
          20. executor.setWaitForTasksToCompleteOnShutdown(true);
          21. //执行初始化
          22. executor.initialize();
          23. return executor;
          24. }
          25. }

           

      • 定义一个专门执行异步操作的线程服务类,用来调用线程池执行异步任务
          1. @Component
          2. @Slf4j
          3. public class ThreadService {
          4. //期望此操作在线程池执行 不会影响原有的主线程
          5. @Async("taskExecutor")
          6. public void updateXXX(LotteryCalculatePerMapper lotteryCalculatePerMapper,Long id){
          7. try{
          8. Thread.sleep(1000);
          9. lotteryCalculatePerMapper.getById(id);
          10. }catch (Exception e){
          11. log.error(e.getMessage());
          12. }
          13. }
          14. }

           

      • 调用线程服务类执行任务
        • threadService.updateXXX(lotteryCalculatePerMapper,id)
    • 使用SpringBoot自带的线程池
      • 通过上线文查看SpringBoot默认注册的线程池
          1. @EnableAsync // 启用异步
          2. @EnableCaching // 启用缓存
          3. @EnableScheduling // 启动定时任务
          4. @SpringBootApplication // springboot本尊
          5. @EnableTransactionManagement // 启动注解事务管理
          6. @Slf4j
          7. public class SpServerApplication {
          8. public static void main(String[] args) {
          9. //可通过上线文找到SpringBoot默认注册的线程池及其情况
          10. ConfigurableApplicationContext context = SpringApplication.run(SpServerApplication.class, args);
          11. ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
          12. ThreadPoolTaskExecutor applicationTaskExecutor = (ThreadPoolTaskExecutor)beanFactory.getSingleton("applicationTaskExecutor");
          13. //默认的核心线程数:8,最大线程数:2147483647,激活数:0,空闲时间:60,队列使用LinkedBlockingQueue,线程池拒绝策略:AbortPolicy
          14. log.info("默认的核心线程数:{},最大线程数:{},激活数:{},空闲线程保留时间:{}",
          15. applicationTaskExecutor.getCorePoolSize(),applicationTaskExecutor.getMaxPoolSize()
          16. ,applicationTaskExecutor.getActiveCount(),applicationTaskExecutor.getKeepAliveSeconds());
          17. }
          18. }

           

      • 在需要的Service中使用
        • 注入线程池
          •  @Autowired  private ThreadPoolTaskExecutor threadPoolTaskExecutor;
        • 在主线程中使用异步线程池执行多个任务
            1. CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            2. lotteryCalculatePerService.lotteryCalculatePer();
            3. }, threadPoolTaskExecutor);
            4. CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            5. lotteryCalculateCountService.lotteryCalculateCount();
            6. }, threadPoolTaskExecutor);
            7. CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.runAsync(() -> {
            8. lotteryCalculateNineService.lotteryCalculateNine();
            9. }, threadPoolTaskExecutor);
            10. //等待所有完成
            11. try {
            12. CompletableFuture.allOf(voidCompletableFuture,voidCompletableFuture1,voidCompletableFuture2).get();
            13. } catch (InterruptedException e) {
            14. throw new RuntimeException(e);
            15. } catch (ExecutionException e) {
            16. throw new RuntimeException(e);
            17. }

             

      • 针对Web场景进行异步操作
        • 无返回值
          •  
            1. @Async("taskExecutor")
            2. @SneakyThrows
            3. public void testVoid(){
            4. Thread.sleep(1000);
            5. log.info("testVoid。。。");
            6. }

             

        • 有返回值
          •  
            1. public String syncData() throws ExecutionException, InterruptedException {
            2. CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            3. lotteryCalculatePerService.lotteryCalculatePer();
            4. }, threadPoolTaskExecutor);
            5. CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            6. lotteryCalculateCountService.lotteryCalculateCount();
            7. }, threadPoolTaskExecutor);
            8. CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.runAsync(() -> {
            9. lotteryCalculateNineService.lotteryCalculateNine();
            10. }, threadPoolTaskExecutor);
            11. //等待所有完成
            12. CompletableFuture.allOf(voidCompletableFuture,voidCompletableFuture1,voidCompletableFuture2).get();
            13. //注:以上执行为异步操作,主程序为顺序执行,CompletableFuture.allOf 起一个挡板作用,以上为异步
            14. return "OK!";
            15. }

             

函数式编程(Lambda)

概述

    • 主要作用
      • 处理大数据量集合效率更高
      • 处理大数据量集合效率更高
      • 简化代码
    • 编程思想
      • 函数式编程思想
      • 匿名内部类

Lambda表达式

    • 语法糖、可推导可省略
    • 基本格式:(参数列表)->{代码}
    • 省略规则
      • 参数类型可以省略
      • 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
      • 方法只有一个参数时小括号可以省略

Stream流

    • Idea工具可支持Stream流调试
      • Trace Current Stream Chain 
    • 常用操作
      • 创建流
        • 集合对象.stream().
        • Arrays.stream(数组). ... 或者使用 Stream.of(数组)........
        • 集合对象.stream().
        • Arrays.stream(数组). ... 或者使用 Stream.of(数组)........
        • map.entrySet().stream()......
      • 中间操作
        • filter
          • 对流中元素进行过滤,符合条件的才会留存下来
          • list/arrays/map.stream.filter(xx-> boolean )....
        • map
          • 对流中元素进行计算或者转换
          • list/arrays/map.stream.map(xx-> {转换逻辑  return y } )....
        • distinct
          • 可以去除流中的重复元素
          • 底层依赖object的equals方法,判断对象是否重复,可进行重写equals方法
          • list/arrays/map.stream.distinct()....
        • sorted
          • 可以对流中元素进行排序
          • 针对对象的排序,可以实现Comparable<xxx> 接口的compareTo方法
          • list/arrays/map.stream.sorted().... 或者 list/arrays/map.stream.sorted((o1,o2)-> o1.xxx > o2.xxx)....
        • limit
          • 可以限制流的元素的最大长度
          • list/arrays/map.stream.limit(n)....
        • filter
          • 对流中元素进行过滤,符合条件的才会留存下来
          • list/arrays/map.stream.filter(xx-> boolean )....
        • map
          • 对流中元素进行计算或者转换
          • list/arrays/map.stream.map(xx-> {转换逻辑  return y } )....
        • distinct
          • 可以去除流中的重复元素
          • 底层依赖object的equals方法,判断对象是否重复,可进行重写equals方法
          • list/arrays/map.stream.distinct()....
        • sorted
          • 可以对流中元素进行排序
          • 针对对象的排序,可以实现Comparable<xxx> 接口的compareTo方法
          • list/arrays/map.stream.sorted().... 或者 list/arrays/map.stream.sorted((o1,o2)-> o1.xxx > o2.xxx)....
        • limit
          • 可以限制流的元素的最大长度
          • list/arrays/map.stream.limit(n)....
        • skip
          • 跳过流中元素的前n个元素,返回剩下元素
          • list/arrays/map.stream.skip(n)....
        • flatmap
          • map只能把一个对象转换成另一个对象;而flatMap可以把一个对象转换成多个对象作为流中元素,同时也可以将多个对象转换为一个对象
          • list/arrays/map.stream.flatmap(xxx-> {... return yyy})....
      • 终结操作
        • foreach
          • 循环遍历
          • list/arrays/map.stream.foreach(xx-> {......})
        • count
          • 获取流中元素个数
          • list/arrays/map.stream.count()
        • min&max
          • 获取流中元素最小值/最大值
          • list/arrays/map.stream.min((s1,s2)-> s1 - s2).get()/max((s1,s2)-> s1 - s2).get())
        • collect
          • 把当前流中元素转换为一个集合
          • list/arrays/map.stream.collect(Collectors.toList())  或 list/arrays/map.stream.collect(Collectors.toSet()) 或 list/arrays/map.stream.collect(Collectors.toMap(xxx-> xxx.getAAA(),xxx.getBBB()))
        • anyMatch
          • 用来判断是否有任意符合匹配条件的元素,结果为boolean类型
          • list/arrays/map.stream.anyMatch(xx-> boolean)
        • allMatch
          • 用来判断是否所有符合匹配条件的元素,结果为boolean类型,只有所有都满足才返回true,否则返回false
          • list/arrays/map.stream.allMatch(xx-> boolean)
        • noneMatch
          • 用来判断流中都不符合条件的元素,结果为boolean类型,只有所有都满足才返回true,否则返回false
          • list/arrays/map.stream.noneMatch(xx-> boolean)
        • findAny
          • 获取流中任意一个元素,不能保证一定获取第一个元素,结果有随机性
          • list/arrays/map.stream.findAny().ifPresent(xxx-> {.....})
        • findFirst
          • 获取流中第一个元素
          • list/arrays/map.stream.findFirst().ifPresent(xxx-> {.....})
        • reduce
          • 对流中的数据按照你制定的计算方式计算出一个结果
          • 将stream流中的元素组合起来,可以传入一个初始值,它会按照我们计算方式依次拿流中元素和初始值的基础上进行计算,计算结果再和后面的元素计算返回
          • 求和:list/arrays/map.stream.map(xxx-> yyy).reduce(0,(a,b)-> a+b) 最大值:list/arrays/map.stream.map(xxx-> yyy).reduce(INTEGER.MAX_VALUE,(a,b)-> a>b ? a : b) 最小值:list/arrays/map.stream.map(xxx-> yyy).reduce(INTEGER.MIN_VALUE,(a,b)-> a<b ? a : b)

Optional

    • 可以用来避免对象获取属性时空指针异常问题
    • Optional.ofNullable(xxx).ifPresent(a-> {..........})
    • 获取安全值,如果我们期望想要获取非空值但又不想判空,不推荐直接使用get()方法
      • orElseGet
        • Optional.ofNullable(xxx).orElseGet(()-> new xxx());
      • orElseThrow
        • Optional.ofNullable(xxx).orElseThrow((Supplier<Throwable>)()-> new RuntimeException("xxx为空"));
    • 过滤用法:filter
      • Optional.ofNullable(xxx).filter(xxx-> boolean).ifPresent(a-> {..........})
    • map
      • Optional.ofNullable(xxx).map(xxx-> {... return aaa}).ifPresent(a-> {..........})

函数式接口

    • 只有一个抽象方法的接口我们称之为函数接口,JDK的函数式接口都加上了@FunctionalInterface注解进行标识,实战中可自定义函数式接口并加上@FunctionalInterface注解

方法引用

    • 在使用lambda时,如果方法体中只有一个方法的调用的话(包括构造方法),我们可以用方法引用进一步简化代码
    • 类名::方法名
    • 如果是静态方法,可以使用类名::方法名
    • 如果我们在重写某个类的方法时,方法体只有一行代码,这行代码调用了某个对象的成员方法且该成员方法的所有参数按照顺序传入了这个成员方法中,此时 可以简写 实例名::方法名
    • 构造器引用: 类名::new
      • 如果我们在重写方法时,方法体只有一行代码,并且这行代码是调用了某个类的构造方法,我们把重写的抽象方法中所有参数按照顺序传入了这个构造方法中,这个时候可以使用引用构造器简写

高级用法

    • 主要是在大数据量情况下,如果有比较、运算等场景,为避免频繁拆装箱导致耗时问题,可使用 mapToInt、MapToLong等替代map方法
      • mapToInt
      • mapToLong
      • mapToDouble
    • 并行流:parallel
      • Stream.of(xxx).parallel().filter(x-> ....).map(x-> ....).reduce(x-> ...)... 或者 使用 xxxx.parallelStream().....
      • 当集合遍历有多个操作时并且数据量较大时可以考虑采用并行流

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/1008858
推荐阅读
相关标签
  

闽ICP备14008679号