【2023】CompletableFuture使用代码案例实习使用场景介绍

news2024/10/7 12:21:59

CompletableFuture

  • 一、介绍
    • 1、概述
    • 2、常用方法
  • 二、方法使用
    • 1、异步操作
      • 1.1、创建任务(runAsync | supplyAsync)
        • runAsync
        • supplyAsync
      • 1.2、获取结果(get | join)
      • 1.3、异常处理(whenComplete | exceptionally)
        • whenComplete
        • exceptionally
    • 2、场景使用
      • 2.1、结果转换(thenApply | thenCompose)
        • thenApply
        • thenCompose
      • 2.2、结果消费(thenAccept | thenAcceptBoth | thenRun)
        • thenAccept
        • thenAcceptBothAsync
        • thenRun
      • 2.3、任务组合(thenCombine)
        • thenCombine
      • 2.4、任务对比(applyToEither | acceptEither | runAfterEither)
        • applyToEither
        • acceptEither
        • runAfterEither
      • 2.4、批量处理任务(allOf | anyOf)
        • allOf
        • anyOf

一、介绍

1、概述

CompletableFuture 是 Java 8 引入的一种异步编程工具,位于 java.util.concurrent 包中。它提供了一种方便的方式来执行异步任务,并在任务完成时执行相应的操作。

  • CompletableFuture是对Future的扩展和增强;CompletableFuture是一种可完成或失败的Future。它提供了一种通用的机制来处理异步操作的结果,包括处理异步任务的完成、异常处理和组合多个异步任务的结果。
  • 并且通过实现CompletionStage实现了对任务编排的能力,执行某一阶段,可以向下执行后续阶段。
  • 异步执行的时候,如果未定义线程池,默认线程池是ForkJoinPool.commonPool(),但一般实际开发中还是尽量自己定义线程池,避免出现因为默认线程池线程被占满造成阻塞问题。

2、常用方法

CompletableFuture的方法中不以Async结尾,意味着Action使用相同的线程执行;而Async可能会使用其它的线程去执行(如果使用相同的线程池,也可能会被同一个线程选中执行)。

方法名描述返回值静态方法
supplyAsync异步执行一个有返回值的任务CompletableFuture
runAsync异步执行一个无返回值的任务CompletableFuture
join获取CompletableFuture异步之后的返回值,抛出的是未经检测异常
get获取CompletableFuture异步之后的返回值,抛出的是经过检查的异常,需要手动处理(抛出或者 try catch)
whenComplete用于在 CompletableFuture 完成(正常或异常完成)后执行指定的操作
exceptionally当CompletableFuture任务发生异常时执行,不发生异常时不执行
thenApply当前任务完成时,执行一个函数并返回新的CompletableFuture
thenCompose当前任务完成时,执行一个函数并返回新的CompletableFuture(同thenApply入参不同)
thenAccept当前一个任务完成时,执行一个消费者函数,没有返回值
thenAcceptBoth当两个CompletableFutures都执行完毕后,执行指定的操作,没有返回值
thenRun当上一阶段任务执行完成后异步执行一个不带任何输入参数的任务;
thenCombine组合两个CompletableFuture的结果,返回新的CompletableFuture
applyToEither对比并向处理的两个任务哪个先执行完就采用哪一个任务的结果进行处理并返回新的结果
acceptEither对比并向处理的两个任务哪个先执行完就采用哪一个任务的结果进行处理直接消费结果,不会返回新的结果
runAfterEither对比并向处理的两个任务哪个先执行完,直接进行下一步操作,不关心上一步的运行结果也无返回
allOf接收future任务对象的数组,当全部任务执行完成后,返回一个新的任务
anyOf接收future任务对象的数组,当有一个任务执行完成后,返回该任务

这些方法用于创建、组合和处理CompletableFuture实例,以实现异步编程。每个方法都具有不同的功能和用途,可以根据具体的需求选择适合的方法来构建

二、方法使用

1、异步操作

1.1、创建任务(runAsync | supplyAsync)

runAsync

runAsync()无返回值,参数为一个 Runnable函数类型,可以指定线程池;如果没有指定会内部使用默认的线程池ForkJoinPool.commonPool()


        Runnable runnable = () -> {

            System.out.println("无返回值的异步任务"+Thread.currentThread().getName());
        };
//			非简写方式
        CompletableFuture.runAsync(runnable).join();

supplyAsync

supplyAsync有返回值,其他的使用和runAsync()基本一致,返回时可以指定类型

//			简写方式
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("有返回值的异步任务"+Thread.currentThread().getName());
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello World!";
        }, Executors.newFixedThreadPool(1));   //指定线程池
        String join = future.join();
        System.out.println(Thread.currentThread().getName()+"结果"+join);

1.2、获取结果(get | join)

get()和join都是用于获取CompletableFuture异步之后的返回值,join()方法抛出的是uncheck异常(即未经检查的异常),不会强制开发者抛出。get()方法抛出的是经过检查的异常,ExecutionException, InterruptedException 需要用户手动处理(抛出或者 try catch)

1.3、异常处理(whenComplete | exceptionally)

whenComplete

用于在 CompletableFuture 完成(正常或异常完成)后执行指定的操作; 用于在CompletableFuture 完成时执行一些附加操作的有用工具,无论是成功完成还是出现异常,(相当于finally部分) ,异常和结果之会返回一个,另外一个会为null。

  • 场景:记录日志、清理资源
  • 代码实现
         CompletableFuture.supplyAsync(() -> {
            System.out.println("无返回值的异步任务线程===="+Thread.currentThread().getName());
            return "----德玛西亚!-----";
        }).whenComplete((u, e) -> { //(u:没有异常时返回的结果,e:有异常时返回的结果)
            System.out.println("future线程======" + Thread.currentThread().getName());

            System.out.println("执行结果:"+u);
            System.out.println("异常输出:" + e);
        }).join();
  • 日志输出
    在这里插入图片描述

exceptionally

exceptionally可用于搭配一起使用:只有当发生异常才执行exceptionally里的任务(相当于catch部分)

  • 代码实现:
        CompletableFuture<String>  future = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Integer i= 10/0;    //模拟一个异常
                return "Hello World!";
         }).whenCompleteAsync((u, e) -> {   //(u:没有异常时返回的结果,e:有异常时返回的结果)

            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println("执行结果:"+u); 
            System.out.println("异常输出:" + e);
            
        }).exceptionally(t -> {    //进行异常处理,无异常时不会执行下面的处理

            System.out.println("执行失败进行异常处理!");
            return "异常XXXX--" + t;
        });

        System.out.println("结果:"+future.join());
  • 日志输出:
    • 有异常时输出:在这里插入图片描述
    • 无异常时输出:
      在这里插入图片描述

2、场景使用

2.1、结果转换(thenApply | thenCompose)

thenApplythenCompose都是用于链式操作,只是入参方式不同而已。
作用:一般用于处理一些需要异步处理的结果该方法不会改变Future的结果类型,执行方式就比如流水线一样,一步一步往下执行,用法和stream流一样,用于做一些中间操作;
比如:你可以将一个字符串结果转换为大写或小写,或者对数字进行一些计算。如: future1->future2->future3

thenApply

thenApply: 接收一个函数作为参数,使用该函数处理上一个CompletableFuture调用的结果,并返回一个具有处理结果的Future对象

  • 代码实现:
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            int result = new Random().nextInt(5) ;
            try {
                TimeUnit.SECONDS.sleep(result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("建立人物模型,耗时:"+result);
            return result;
        }, Executors.newFixedThreadPool(5));

//        thenApply: 接收一个函数作为参数,使用该函数处理上一个CompletableFuture调用的结果,并返回一个具有处理结果的Future对象

        CompletableFuture<Integer> future2 = future1.thenApply(number -> {  //把future1的结果作为入参
            int result = new Random().nextInt(5) ;
            try {
                TimeUnit.SECONDS.sleep(result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("加载模型骨骼,耗时:"+result);
            return result+number;
        });
        
        System.out.println("全部加载完成,耗时:"+future2.join()+"y");
  • 日志输出:
    在这里插入图片描述

thenCompose

thenCompose:的参数为一个返回CompletableFuture实例的函数(而这个实例的参数是先前计算步骤的结果),其他的使用上和thenApply没有区别。

  • 代码实现:
//			拼接前面thenApply部分的代码
        CompletableFuture<Integer> future3 = future2.thenCompose(param ->
                CompletableFuture.supplyAsync(() -> {
                    int result = new Random().nextInt(5) ;
                    try {
                        TimeUnit.SECONDS.sleep(result);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println("加载模型皮肤,耗时:"+result);
                    return result+param;
                })
        );
          不简写的方式
//        CompletableFuture<Integer> future4 = future2.thenCompose(new Function<Integer, CompletionStage<Integer>>() {
//            @Override
//            public CompletionStage<Integer> apply(Integer param) {
//                return CompletableFuture.supplyAsync(new Supplier<Integer>() {
//                    @Override
//                    public Integer get() {
//                        int result = new Random().nextInt(5);
//                        try {
//                            TimeUnit.SECONDS.sleep(result);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                        System.out.println("加载模型皮肤,耗时:" + result);
//                        return result + param;
//                    }
//                });
//            }
//        });

        System.out.println("全部加载完成,耗时:"+future3.join()+"y");
  • 日志输出:
    在这里插入图片描述

2.2、结果消费(thenAccept | thenAcceptBoth | thenRun)

thenAccept

thenAccept用于异步处理上一个Future任务的结果,并且会把结果消费掉,无返回值
作用:比如完成一些操作需要一个前置的条件,并且通过异步执行不需要阻塞住当前线程,可以通过异步同时处理多个任务

    public static void main(String[] args) {
//        消费之前,有返回Integer
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int number = new Random().nextInt(10);
            System.out.println("加载商城页面" + number);
            return number;
        });
        System.out.println("商城页面加载成功:==="+future1.join()+"===继续加载商城内置页面!");


        CompletableFuture<Void> future2 = future1.thenAcceptAsync(number -> {  //结果消费掉之后会没有返回值
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int n2 = number * 2;
            System.out.println("加载商城英雄页面:" + n2);
        });
        CompletableFuture<Void> future3 = future1.thenAcceptAsync(number -> {  //结果消费掉之后会没有返回值
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            int n2 = number * 3;
            System.out.println("加载商城皮肤页面:" + n2);
        });
        future2.join();
        future3.join();
        System.out.println("商城内置页面也加载成功:");
    }

thenAcceptBothAsync

thenAcceptBothAsync会消费两个future的结果,x当前的,y入参的,无返回值
作用:主要用于当需要两个前置任务完成后,再消费两个前置任务的结果去执行thenAcceptBoth的任务(需要注意的是该方法的前置任务的执行顺序是无法确认的)

  • 代码实现:
        //        消费之前,有返回Integer
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(10);
            System.out.println("工商银行储蓄卡余额:" + number);
            return number;
        });
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(10);
            System.out.println("工商银行信用卡余额:" + number);
            return number;
        });

//        thenAcceptBothAsync会消费两个future的结果,x当前的,y入参的,无返回值
//                作用:主要用于当需要两个前置任务完成后,
//                  再消费两个前置任务的结果去执行thenAcceptBoth的任务(需要注意的是该方法的前置任务的执行顺序是无法确认的)

         future1.thenAcceptBothAsync(future2, (x, y) ->  //会消费掉两个前置任务的结果
                System.out.println("工商银行总余额:" + (x + y))
        );
  • 日志输出:
    在这里插入图片描述

thenRun

thenRun主要在前任务执行完成后异步执行一个不带任何输入参数的任务;一般用于某些清理,日志记录,关闭资源、释放锁等

  • 代码实现:
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            int number = new Random().nextInt(10);

            System.out.println("初始值:" + number);

            return number;
        });

//        thenRun:主要在前任务执行完成后异步执行一个不带任何输入参数的任务;一般用于某些清理,日志记录,关闭资源、释放锁等
        future1.thenRun(()->{
            System.out.println(Thread.currentThread().getName()+"执行run关闭资源");
        });
  • 日志输出:
    在这里插入图片描述

2.3、任务组合(thenCombine)

thenCombine

thenCombine:和 thenAcceptBoth使用类似,都是合并使用两个前置任务future的结果,进行最终处理,但thenCombine会把组合处理然后返回一个新的值
场景:一般用于并行数据获取与组合和一些数据转换与组合

  • 代码实现
        int i = 10;
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(10) * i;
            System.out.println("获取用户的信息:" + number);
            return number;
        });

        CompletableFuture<Integer> future2 =CompletableFuture.supplyAsync(()->{
        int number = new Random().nextInt(10) * i;
        System.out.println("获取用户的订单信息:"+number);
        return number;
        });
        
        //不简写写法
//        CompletableFuture<Integer> result = future1
//                .thenCombine(future2, new BiFunction<Integer, Integer, Integer>() {
//                    @Override
//                    public Integer apply(Integer x, Integer y) {
//                        return x + y;
//                    }
//                });

//       
        CompletableFuture<Integer> future3 = future1.thenCombine(future2, (x, y) -> {
            Integer sum = x + y;
            System.out.println("进行合并处理:" + sum);
            return sum;
        });
        System.out.println("最终处理结果信息:"+future3.get());

  • 日志输出:
    在这里插入图片描述

2.4、任务对比(applyToEither | acceptEither | runAfterEither)

applyToEither

applyToEither: 主要用于对比并向处理的两个任务哪个先执行完就采用哪一个任务的结果进行处理。
场景:假设我们需要从两个不同的远程服务器获取数),或者采用两种通讯协议(SSH、HTTP)获取数据,可以异步通过applyToEither择优选择最快方式的得到结果进行处理

  • 代码实现:
        int i= 250;
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("使用银河计算机计算结果为:" + i+",耗时:"+number+"秒");
            return number;
        });

        CompletableFuture<Integer> future2 =CompletableFuture.supplyAsync(()->{
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("使用长城计算机计算结果为:" + i+",耗时:"+number+"秒");
            return number;
        });
		//applyToEither会得到最先执行完成的结果,进行处理,并返回一个新的结果
        CompletableFuture<String> future3 = future1.applyToEither(future2, (x) -> {
            System.out.println("结果计算成功" );
            return "最终结果执行耗时:"+x ;
        });

        System.out.println(future3.join());
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  • 日志输出:
    在这里插入图片描述

acceptEither

acceptEitherAsync:和applyToEither意思和使用都一样,只不过acceptEither会把前置任务的结果直接消费掉,不会有返回值,
场景:适用于在两个异步操作之一完成时执行一些副作用的情况

  • 代码实现:
        int i= 10;
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("使用银河计算机计算结果为:" + i+",耗时:"+number+"秒");
            return "银河计算机";
        });

        CompletableFuture<String> future2 =CompletableFuture.supplyAsync(()->{
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("使用长城计算机计算结果为:" + i+",耗时:"+number+"秒");
            return "长城计算机";
        });

//        acceptEitherAsync:和applyToEither意思和使用都一样,只不过acceptEither会把前置任务的结果直接消费掉,不会有返回值
        future1.acceptEitherAsync(future2, (x) -> {
            System.out.println("最终处理结果采用:" + x);
        }).join();


        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  • 日志输出:
    在这里插入图片描述

runAfterEither

runAfterEither:和前面俩一样,也是两个前置任务进行比较,看哪个先执行完成,就进行下一步操作,但runAfterEither不会关心前置任务的处理结果(无入参),也没返回值
适用于在两个异步操作之一完成后执行一些无需依赖结果的操作。

  • 代码实现:
        int i= 10;
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("通过http传输数据:" + i+",耗时:"+number+"秒");
            return number;
        });


        CompletableFuture<Integer> future2 =CompletableFuture.supplyAsync(()->{
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("通过web socket传输数据:" + i+",耗时:"+number+"秒");
            return number;
        });
		//没有参数也没有返回值
        future1.runAfterEither(future2,()->{
            System.out.println("任务传输成功!");
        }).join();
  • 日志输出:
    在这里插入图片描述

2.4、批量处理任务(allOf | anyOf)

allOf

allOf无返回值,接收future任务对象的数组作为参数并且返回一个新的CompletableFuture。这个新的
CompletableFuture<Void> 在所有传入的 CompletableFuture对象都完成后才会完成,无返回值。
场景:并行执行一组独立的异步任务,并在所有任务完成后进行下一步操作;等待多个异步操作完成后进行某种聚合操作等

-代码实现:

        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i+"写入mysql成功,耗时:"+number);
            return "mysql";
        });

        CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i+"写入sqlserver成功,耗时:"+number);

        });
        CompletableFuture.allOf(future1, future2).join();
        System.out.println("写入数据库成功,执行后续。。。。");
  • 日志输出:
    在这里插入图片描述

anyOf

anyOfCompletableFuture的静态方法,主要用于接收多个Future任务,然后从中选取到最先执行完的任务的结果进行使用;anyOf是静态方法,并且可以接收多个Future任务;
场景:同样适用于当并发执行多个独立任务时,从中选取最快的结果进行使用的场景;或者是超时处理的场景,当你希望在一段时间内完成多个任务中的任何一个,并在超时发生时做一些特定操作时使用。

  • 代码实现:
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("乌龟到达终点,耗时:"+number+"秒");
            return "乌龟";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("兔子到达终点,耗时:"+number+"秒");
            return "兔子";
        });
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            int number = new Random().nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(number);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("蜗牛到达终点,耗时:"+number+"秒");
            return "蜗牛";
        });
        
        CompletableFuture<Object> result = CompletableFuture.anyOf(future1, future2 ,future3);
        System.out.println("获得第一名是:"+result.join());

        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

  • 日志输出:
    在这里插入图片描述
    —部分介绍引用 https://blog.csdn.net/sermonlizhi/article/details/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/971160.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习(吴恩达第一课)

课程链接 文章目录 第一周1、机器学习定义2、监督学习(Supervised learning)1、回归(Regression)2、分类(Classification) 3、无监督学习(Unsupervised learning)4、线性回归模型5、代价函数6、梯度下降(Gradient descent)1、学习率2、用于线性回归的梯度下降 第二周(多维特征…

根据梁山好汉的武力值排交椅:python知识点串联sorted,enumerate,zip,list comprehension

故事发生的背景是这样的&#xff0c;水泊梁山好汉武松&#xff0c;鲁智深&#xff0c;杨志三人在上梁山前&#xff0c;共同落草过二龙山&#xff0c;好汉们需要根据其战斗力的高低来排座次&#xff0c;战斗力最高的坐第一把交椅&#xff0c;其次的坐第二把交椅&#xff0c;以此…

【业务功能篇96】微服务-springcloud-springboot-认证服务-登录注册功能-Auth2.0-分布式session

5.登录功能 通过最基础的登录操作来完成登录处理 登录页面处理 认证服务的处理 /*** 注册的方法* return*/PostMapping("/login")public String login(LoginVo loginVo , RedirectAttributes redirectAttributes){R r memberFeginService.login(loginVo);if(r.getC…

22 元类技术(面向切片编程)|ORM的实现|抽象类与接口类

文章目录 前情知识补充hasattr 函数setattr函数getattr函数join 函数 元类技术使用type创建类什么是元类&#xff08;概念总结&#xff09;\_\_metaclass\_\_属性使用metaclass 的函数方式进行创建类使用metaclass 的类方式进行创建类 自定义元类 元类实现ORM接口类与抽象类抽象…

分治NTT/在线卷积

https://www.luogu.com.cn/problem/P4721 已知 g g g&#xff0c;求 考虑分治&#xff0c;现在在 [ l , r ] [l,r] [l,r]&#xff0c;先计算 [ l , m i d ] [l, mid] [l,mid]&#xff0c;然后计算 [ l , m i d ] [l, mid] [l,mid] 对 [ m i d 1 , r ] [mid1,r] [mid1,r…

Java elasticsearch scroll模板实现

一、scroll说明和使用场景 scroll的使用场景&#xff1a;大数据量的检索和操作 scroll顾名思义&#xff0c;就是游标的意思&#xff0c;核心的应用场景就是遍历 elasticsearch中的数据&#xff1b; 通常我们遍历数据采用的是分页&#xff0c;elastcisearch还支持from size的方…

Redis基础知识(二):事务机制

文章目录 一、什么是事务机制&#xff1f;二、Redis模式下如何实现事务机制&#xff1f;2.1 显式开启一个事务2.2 将命令入队列Queue2.3 执行事务或丢弃2.4 EXEC命令执行示例2.5 DISCARD命令&#xff1a;放弃事务2.6 因为命令错误导致的事务回滚 三、Redis事务机制能实现哪些属…

气象监测——关于气象监测站的介绍

在科技日益发展的今天&#xff0c;人类对自然环境的认识和依赖程度越来越高。气象监测站作为用于收集、分析和传播气象数据的设施&#xff0c;为天气预报、气候变化研究、灾害防治等方面提供数据支持。随着科技的不断进步&#xff0c;气象监测站已经发展成为集多种高科技设备于…

leetcode 594.最长和谐子序列(滑动窗口)

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;最长和谐子序列 思路&#xff1a; 第一步先将数组排序&#xff0c;在使用滑动窗口&#xff08;同向双指针&#xff09;&#xff0c;定义 left right 下标&#xff0c;比如这一组数 {1,3,2,2,5,2,3,7} 排序后 {1,2,2,2,3,…

Java问题诊断和排查工具

文章目录 一、前言二、Java问题诊断和排查工具1、JDK自带工具2、常用命令3、JAVA Dump&#xff1a;3.1、jps3.2、jstack3.3、jmap3.3.1、jmap -heap pid:查看堆使用情况3.3.2、jmap -histo pid&#xff1a;查看堆中对象数量和大小3.3.3、jmap -dump:formatb,fileheapdump pid&a…

教你如何高效批量分割长视频,让你的视频制作更轻松

在视频制作过程中&#xff0c;我们常常需要从长视频中分割出一些重要的片段&#xff0c;以便进行后续的编辑和处理。然而&#xff0c;这是一项耗时且繁琐的任务。今天&#xff0c;我们将为您介绍一种高效分割长视频的方法&#xff0c;让您在视频制作中更高效、更便捷。 首先&am…

C. To Add or Not to Add

题目&#xff1a; 样例1&#xff1a; 输入 5 3 6 3 4 0 2输出 3 4 样例2&#xff1a; 输入 3 4 5 5 5输出 3 5 样例3&#xff1a; 输入 5 3 3 1 2 2 1输出 4 2 思路&#xff1a; 贪心题目&#xff0c;化分离数为块。这里要注意的是 需要进行的排序 以及操作的过程是什么样子…

【本地代码问题】启动程序,报错:java.lang.IllegalArgumentException: No selectors

启动程序的时候报错了 问题怎么出现的解决方式&#xff0c;注释掉jetty的内容&#xff0c;回归tomcat的使用 问题怎么出现的 我本地启动程序的时候报错了&#xff1a;报的是这个错误&#xff0c;可能和容器的选择有关吧 解决方式&#xff0c;注释掉jetty的内容&#xff0c;回…

2.2 PE结构:文件头详细解析

PE结构是Windows系统下最常用的可执行文件格式&#xff0c;理解PE文件格式不仅可以理解操作系统的加载流程&#xff0c;还可以更好的理解操作系统对进程和内存相关的管理知识&#xff0c;DOS头是PE文件开头的一个固定长度的结构体&#xff0c;这个结构体的大小为64字节&#xf…

MyBatisPlus之逻辑删除、MyBatisPlus解决并发问题的乐观锁机制

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 MyBatisPlus 一、 逻辑删除1.1 数据库表中添加逻辑…

广州华锐互动:3D数字孪生楼宇资产管理系统展示楼宇实时信息

3D数字孪生楼宇资产管理系统由广州华锐互动开发&#xff0c;是一种基于数字孪生技术的智能化展示平台&#xff0c;它可以将楼宇的各项数据进行实时展示&#xff0c;为楼宇的管理者和使用者提供便捷的信息查询和服务。以下是一些实用功能&#xff1a; 1.实时监控&#xff1a;实时…

问道管理:刚刚,“金九”来了?

今天早盘&#xff0c;A股商场可谓“全面开花”。 银行、白酒等权重板块携手发力&#xff0c;带动上证指数、深证成指半日涨超1%&#xff1b;北交所股票更是全线飘红&#xff0c;北证50指数盘中最大涨幅超越8%&#xff0c;半日上涨5.85%。 到午间休市&#xff0c;A股商场超越3…

【C++】智能指针(RAII)详解

我们在上篇文章中&#xff08;异常处理详解&#xff09;提到了 RAII 。那么本篇文章会对此进行详解。重点是智能指针的详解。其中会讲解到 RAII 思想、auto_ptr、unique_ptr、shared_ptr、weak_ptr、循环引用问题。希望本篇文章会对你有所帮助。 文章目录 一、为什么需要智能指…

【java】【项目实战】[外卖九]项目优化(缓存)

目录 一、问题说明 二、环境搭建 2.1 Git管理代码 2.1.1 创建本地仓库 2.1.2 创建远程仓库 2.1.3 创建分支--》推送到远程仓库 2.2 maven坐标 2.3 配置文件application.yml 2.4 配置类RedisConfig 三、缓存短信验证码 3.1 实现思路 3.2 代码改造 3.2.1 UserContro…

CS420 课程笔记 P5 - 内存编辑 数据类型

文章目录 IntroductionData typesBooleansNegative numbers (Signed integers)Floating-point numbers (fractional numbers) Unknown value scansHealth findingFloat finding (Player position hack / Teleport hack) Additional things Introduction 这节课将结束数据类型并…