写点什么

Java 实战 1

作者:thinkers
  • 2024-03-01
    广东
  • 本文字数:6175 字

    阅读完需:约 20 分钟

线程池

SpringBoot + 线程池 使用

○       自定义线程池

■       定义一个线程池配置类

●      

      

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

■       定义一个专门执行异步操作的线程服务类,用来调用线程池执行异步任务

●      

@Component @Slf4j public class ThreadService {       //期望此操作在线程池执行 不会影响原有的主线程       @Async("taskExecutor")       public void updateXXX(LotteryCalculatePerMapper lotteryCalculatePerMapper,Long id){     try{                   Thread.sleep(1000);                   lotteryCalculatePerMapper.getById(id);             }catch (Exception e){                   log.error(e.getMessage());             }       } }
复制代码

■       调用线程服务类执行任务

●       threadService.updateXXX(lotteryCalculatePerMapper,id)

○       使用 SpringBoot 自带的线程池

■       通过上线文查看 SpringBoot 默认注册的线程池

●      

@EnableAsync    // 启用异步  @EnableCaching // 启用缓存 @EnableScheduling // 启动定时任务 @SpringBootApplication // springboot本尊 @EnableTransactionManagement // 启动注解事务管理 @Slf4j public class SpServerApplication {    public static void main(String[] args) {       //可通过上线文找到SpringBoot默认注册的线程池及其情况       ConfigurableApplicationContext context = SpringApplication.run(SpServerApplication.class, args);       ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();       ThreadPoolTaskExecutor applicationTaskExecutor = (ThreadPoolTaskExecutor)beanFactory.getSingleton("applicationTaskExecutor");       //默认的核心线程数:8,最大线程数:2147483647,激活数:0,空闲时间:60,队列使用LinkedBlockingQueue,线程池拒绝策略:AbortPolicy       log.info("默认的核心线程数:{},最大线程数:{},激活数:{},空闲线程保留时间:{}",                  applicationTaskExecutor.getCorePoolSize(),applicationTaskExecutor.getMaxPoolSize()     ,applicationTaskExecutor.getActiveCount(),applicationTaskExecutor.getKeepAliveSeconds());    } }
复制代码

■       在需要的 Service 中使用

●       注入线程池

○        @Autowired  private ThreadPoolTaskExecutor threadPoolTaskExecutor;

●       在主线程中使用异步线程池执行多个任务

○      

CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {      lotteryCalculatePerService.lotteryCalculatePer();   }, threadPoolTaskExecutor);   CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {      lotteryCalculateCountService.lotteryCalculateCount();   }, threadPoolTaskExecutor);   CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.runAsync(() -> {      lotteryCalculateNineService.lotteryCalculateNine();   }, threadPoolTaskExecutor);   //等待所有完成   try {      CompletableFuture.allOf(voidCompletableFuture,voidCompletableFuture1,voidCompletableFuture2).get();   } catch (InterruptedException e) {      throw new RuntimeException(e);   } catch (ExecutionException e) {      throw new RuntimeException(e);   }
复制代码

■       针对 Web 场景进行异步操作

●       无返回值

○        @Async("taskExecutor")  @SneakyThrows  public void testVoid(){   Thread.sleep(1000);   log.info("testVoid。。。");  }

●       有返回值

○        

@Async("taskExecutor")  @SneakyThrows  public CompletableFuture<String> testReturn(){     Thread.sleep(1000);     return CompletableFuture.completedFuture(lotteryForecastService.syncData());  }
public String syncData() throws ExecutionException, InterruptedException {   CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {     lotteryCalculatePerService.lotteryCalculatePer();   }, threadPoolTaskExecutor);   CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {     lotteryCalculateCountService.lotteryCalculateCount();   }, threadPoolTaskExecutor);   CompletableFuture<Void> voidCompletableFuture2 = CompletableFuture.runAsync(() -> {     lotteryCalculateNineService.lotteryCalculateNine();   }, threadPoolTaskExecutor);   //等待所有完成   CompletableFuture.allOf(voidCompletableFuture,voidCompletableFuture1,voidCompletableFuture2).get();   //注:以上执行为异步操作,主程序为顺序执行,CompletableFuture.allOf 起一个挡板作用,以上为异步   return "OK!";  
复制代码

函数式编程(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().....

■       当集合遍历有多个操作时并且数据量较大时可以考虑采用并行流

发布于: 刚刚阅读数: 5
用户头像

thinkers

关注

笑看风云,云淡风轻! 2017-12-12 加入

一个无聊、平凡的人

评论

发布
暂无评论
Java实战1_线程池、Lambda、Java实战_thinkers_InfoQ写作社区