多线程进阶-JUC

72 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天

1.四大函数式接口(必须掌握)

新时代的程序员:lambda表达式、链式编程、函数式接口、Stream流式计算

函数式接口:只有一个方法的接口

 @FunctionalInterface
 public interface Runnable {
     /**
      * When an object implementing interface <code>Runnable</code> is used
      * to create a thread, starting the thread causes the object's
      * <code>run</code> method to be called in that separately executing
      * thread.
      * <p>
      * The general contract of the method <code>run</code> is that it may
      * take any action whatsoever.
      *
      * @see     java.lang.Thread#run()
      */
     public abstract void run();
 }

超级多的@FunctionalInterface

简化编程模型,在新版本的框架底层大量应用

foreach()的参数也是一个函数式接口(消费者类的函数式接口)

image-20221009155538851

代码测试:

Function函数式接口

Function函数式接口: 有一个输入参数 ,有一个输出

只要有 函数式接口 可以 用 lambda表达式

 public class demo1 {
     public static void main(String[] args) {
 //        Function function = new Function<String,String>() {
 //            @Override
 //            public String apply(String str) {
 //                return str;
 //            }
 //        };
 ​
         Function<String,String> function  = (str)->{return str;};
 ​
         System.out.println(function.apply("asd"));
     }
 ​
 }
 ​

断定型接口:有一个输入参数,返回值只能是 布尔值!

image-20221009162101975

 public class Demo2 {
     public static void main(String[] args) {
         //判断字符串是否为空
 //        Predicate<String> predicate = new Predicate<String>() {
 //            @Override
 //            public boolean test(String str) {
 //                return str.isEmpty();
 //            }
 //        };
         Predicate<String> predicate =(str)->{ return str.isEmpty();};
         System.out.println(predicate.test("asd"));
     }
 }
 ​

Consumer消费型接口

消费型接口 没有返回值!只有输入!

image-20221009163802755

 public class Demo3 {
     public static void main(String[] args) {
 ​
 //        Consumer <String> consumer = new Consumer<String>() {
 //            @Override
 //            public void accept(String s) {
 //                System.out.println(s);
 //            }
 //        };
 ​
         Consumer <String> consumer =(s)->{ System.out.println(s);};
         consumer.accept("add");
     }
 }

Supplier接口

供给型接口,只返回,不输入

image-20221009163921453

2. Stream流式计算

大数据: 存储+计算

存储:集合、MySQL

计算:流式计算~

= 链式编程 =
 public class Test {
     public static void main(String[] args) {
         User user1 = new User(1,"a",21);
         User user2 = new User(2,"b",22);
         User user3 = new User(3,"c",23);
         User user4 = new User(4,"d",24);
         User user5 = new User(5,"e",25);
         User user6 = new User(6,"f",26);
         List<User> list = Arrays.asList(user1, user2, user3, user4, user5, user6);
 ​
         //计算交给流
         //链式编程!!!!
         list.stream()
                 .filter((u)->{ return u.getId()%2==0; })
                 .filter((u)->{return u.getAge()>23;})
                 .map((u)->{return u.getName().toUpperCase();})
                 .sorted((uu1,uu2)->{
                     return uu2.compareTo(uu1);
                 })
                 .limit(1)
                 .forEach(System.out::println);
     }
 }
 ​

3. Frokjoin

什么 Frokjoin

ForkJoin 在JDK1.7,并行执行任务!提高效率~。在大数据量速率会更快!

大数据中:MapReduce 核心思想->把大任务拆分为小任务!

image-20221009192605621

ForkJoin 特点: 工作窃取!

image-20221009192945080

如何使用ForkJoin?

  • 1、通过ForkJoinPool来执行
  • 2、计算任务 execute(ForkJoinTask<?> task)

image-20221009194339350

  • 3、计算类要去继承ForkJoinTask;

ForkJoin的计算类!

 package com.ogj.forkjoin;
 ​
 import java.util.concurrent.RecursiveTask;
 ​
 public class ForkJoinDemo extends RecursiveTask<Long> {
 ​
     private long star;
     private long end;
 ​
     //临界值
     private long temp=1000000L;
 ​
     public ForkJoinDemo(long star, long end) {
         this.star = star;
         this.end = end;
     }
 ​
     /**
      * 计算方法
      * @return Long
      */
     @Override
     protected Long compute() {
         if((end-star)<temp){
             Long sum = 0L;
             for (Long i = star; i < end; i++) {
                 sum+=i;
             }
 //            System.out.println(sum);
             return sum;
         }else {
             //使用forkJoin 分而治之 计算
             //计算平均值
             long middle = (star+ end)/2;
             ForkJoinDemo forkJoinDemoTask1 = new ForkJoinDemo(star, middle);
             forkJoinDemoTask1.fork();  //拆分任务,把线程任务压入线程队列
             ForkJoinDemo forkJoinDemoTask2 = new ForkJoinDemo(middle, end);
             forkJoinDemoTask2.fork();  //拆分任务,把线程任务压入线程队列
             long taskSum = forkJoinDemoTask1.join() + forkJoinDemoTask2.join();
             return taskSum;
         }
     }
 }
 ​
 ​

测试类!

 package com.ogj.forkjoin;
 ​
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.ForkJoinTask;
 import java.util.stream.LongStream;
 ​
 public class Test {
     public static void main(String[] args) throws ExecutionException, InterruptedException {
         test1();
         test2();
         test3();
     }
 ​
     /**
      * 普通计算
      */
     public static void test1(){
         long star = System.currentTimeMillis();
         long sum = 0L;
         for (long i = 1; i < 20_0000_0000; i++) {
             sum+=i;
         }
         long end = System.currentTimeMillis();
         System.out.println("sum="+"时间:"+(end-star));
         System.out.println(sum);
     }
 ​
     /**
      * 使用ForkJoin
      */
     public static void test2() throws ExecutionException, InterruptedException {
         long star = System.currentTimeMillis();
         ForkJoinPool forkJoinPool = new ForkJoinPool();
         ForkJoinTask<Long> task = new ForkJoinDemo(0L, 20_0000_0000L);
         ForkJoinTask<Long> submit = forkJoinPool.submit(task);
         Long aLong = submit.get();
         System.out.println(aLong);
         long end = System.currentTimeMillis();
         System.out.println("sum="+"时间:"+(end-star));
     }
 ​
 ​
     /**
      * 使用Stream 并行流
      */
     public static void test3(){
         long star = System.currentTimeMillis();
         //Stream并行流()
         long sum = LongStream.range(0L, 20_0000_0000L).parallel().reduce(0, Long::sum);
         System.out.println(sum);
         long end = System.currentTimeMillis();
         System.out.println("sum="+"时间:"+(end-star));
     }
 }
 ​
 ​
 ​