JUC aprendizaje 2

1 Cálculo de transmisión

1. Cuatro interfaces funcionales

1. Tipo de interfaz

imagen-20200811213746258 imagen-20200811213755511

2. Ejemplos

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class StreamDemo02 {
    
    
   public static void main(String[] args) {
    
    
      functionTest();
      predicateTest();
      consumerTest();
      supplierTest();
   }

   //1、函数式接口<String, Integer><输入类型,输出类型>
//    Function <String, Integer> function = new Function<String, Integer>() {
    
    
//       @Override
//       public Integer apply(String s) {
    
    
//          return 1024;
//       }
//    };
   private static void functionTest() {
    
    
      Function<String, Integer> function = (s) -> {
    
    
         return 1024;
      };
      System.out.println(function.apply("abc")); //1024
   }

   //2、断定型接口 输入参数类型 String,返回boolean类型
//    Predicate<String> predicate = new Predicate<String>() {
    
    
//       @Override
//       public boolean test(String s) {
    
    
//          return false;
//       }
//    };
   private static void predicateTest() {
    
    
      Predicate<String> predicate = (s) -> {
    
    
         return s.isEmpty();
      };
      System.out.println(predicate.test("abc"));  //false
   }

   //3、消费型接口 输入类型 输出为void
   //    Consumer<String> consumer = new Consumer<String>() {
    
    
//       @Override
//       public void accept(String s) {
    
    
//
//       }
//    };

   private static void consumerTest() {
    
    
      Consumer<String> consumer = (s) -> {
    
    
         System.out.println("进入消费数据接口中");
      };
      consumer.accept("param");
   }

   //4、供给型接口(和消费者相反) 无输出参数,又赶回参数
//    Supplier<String> supplier = new Supplier<String>() {
    
    
//       @Override
//       public String get() {
    
    
//          return null;
//       }
//    };
   private static void supplierTest() {
    
    
      Supplier<String> supplier = () -> {
    
    
         return "hello world!";
      };
      System.out.println(supplier.get());
   }
}

2. Stream

1. Introducción

(1) ¿Qué es exactamente una corriente? Es un canal de datos, utilizado para manipular la secuencia de elementos generados por la fuente de datos (colección, matriz, etc.).
"¡Los conjuntos se tratan de datos y los flujos se tratan de cálculos!".

2. Características

(1) Stream en sí no almacena elementos.

(2) Stream no cambia el objeto de origen. En su lugar, devolverán un nuevo Stream con el resultado.

(3) Las operaciones de flujo se ejecutan de forma retrasada. Esto significa que esperarán hasta que se necesiten los resultados antes de ejecutar.

3. Etapa

(1) Crear una secuencia: una fuente de datos (matriz, colección).

(2) Operación intermedia: una operación intermedia que procesa los datos de la fuente de datos.

(3) Operación de terminación: una operación de terminación, que ejecuta una cadena intermedia de operaciones y produce un resultado.

4. Código de implementación

@Data
@NoArgsConstructor
@AllArgsConstructor
class User {
    
    
   private Integer id;
   private String userName;
   private int age;
}

/**
 * 1、题目:请按照给出数据,找出同时满足
 * 偶数ID且年龄大于24且用户名转为大写且用户名字母倒排序
 * 最后只输出一个用户名字
 * 2、源头=>中间流水线=>结果
 */
public class StreamDemo01 {
    
    
   public static void main(String[] args) {
    
    
      User u1 = new User(11, "a", 23);
      User u2 = new User(12, "b", 24);
      User u3 = new User(13, "c", 22);
      User u4 = new User(14, "d", 28);
      User u5 = new User(16, "e", 26);

      List<User> list = Arrays.asList(u1, u2, u3, u4, u5);

      list.stream().filter(p -> {
    
    
         return p.getId() % 2 == 0;
      }).filter(p -> {
    
    
         return p.getAge() > 24;
      }).map(f -> {
    
    
         return f.getUserName().toUpperCase();
      }).sorted((o1, o2) -> {
    
    
         return o2.compareTo(o1);
      }).limit(1).forEach(System.out::println);
   }
}

2 Marco de fusión de ramas

1. Principio

Bifurcación: divide una tarea compleja en otras más pequeñas.
Unirse: combine los resultados de la tarea dividida.

imagen-20200812174341306 imagen-20200812174347684

2. Categorías relacionadas

1 、 ForkJoinPool

imagen-20200812174432507

Analogía de rama y grupo de fusión => grupo de subprocesos.

2 、 ForkJoinTask

imagen-20200812174455462

ForkJoinTask 类比 => FutureTask。

3 、 RecursiveTask

imagen-20200812174519297

Tarea recursiva: después de la herencia, puede realizar la tarea de llamada recursiva (autoajuste).

class Fibonacci extends RecursiveTask<Integer> {
    
    
   final int n;
   Fibonacci(int n) {
    
     this.n = n; }
   Integer compute() {
    
    
     if (n <= 1)
       return n;
     Fibonacci f1 = new Fibonacci(n - 1);
     f1.fork();
     Fibonacci f2 = new Fibonacci(n - 2);
     return f2.compute() + f1.join();
   }
 }

3. Código de implementación

class MyTask extends RecursiveTask<Integer> {
    
    
   //10以内进行拆分(计算临界)
   private static final Integer ADJUST_VALUE = 10;
   private int begin; //开始 0
   private int end; //结束 100
   private int result;

   public MyTask(int begin, int end) {
    
    
      this.begin = begin;
      this.end = end;
   }

   @Override
   protected Integer compute() {
    
    
      if ((end - begin) <= ADJUST_VALUE) {
    
    
         for (int i = begin; i <= end; i++) {
    
    
            result = result + i;
         }
      } else {
    
    
         int middle = (begin + end) / 2;
         MyTask task01 = new MyTask(begin, middle);
         MyTask task02 = new MyTask(middle + 1, end);
         task01.fork();  //回来调用compute方法
         task02.fork();
         result = task01.join() + task02.join();
      }
      return result;
   }
}

/**
 * 分支合并例子
 * ForkJoinPool
 * ForkJoinTask
 * RecursiveTask
 */
public class ForkJoinDemo {
    
    
   public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
      MyTask myTask = new MyTask(0, 100); //任务
      ForkJoinPool forkJoinPool = new ForkJoinPool();
      ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);
      System.out.println(forkJoinTask.get());
      forkJoinPool.shutdown();
   }
}

3 llamada asincrónica

1. Principio

imagen-20200812180030241

2. Código de implementación

/**
 * 1、做完子线程的任务后,调用子线程(异步调用)
 */
public class CompletableFutureDemo {
    
    

   public static void main(String[] args) throws Exception {
    
    

      //异步调用:没有返回值,只是启动一个线程去干活。
//        CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(()->{
    
    
//            System.out.println(Thread.currentThread().getName()+"\t completableFuture1");
//        });
//        completableFuture1.get();

      //异步回调 supply:供给型函数
      CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {
    
    
         System.out.println(Thread.currentThread().getName() + "\t completableFuture2");
//       int i = 10 / 0;
         return 1024;
      });
      //whenComplete 有两个参数,没有返回值(类似消费者,获取线程中的函数)
      System.out.println(completableFuture2.whenComplete((t, u) -> {
    
    
         //正常完成,走该分支
         //-------t------1024
         System.out.println("-------t------" + t);
         //       -------u------null
         System.out.println("-------u------" + u); //异常信息
      }).exceptionally(f -> {
    
    
         //异常完成,走该分支
         System.out.println("-----exception---------" + f.getMessage());
         return 444;
         //返回正确结果:1024
         //返回异常结果:444
      }).get());
   }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43334389/article/details/114113523
Recomendado
Clasificación