JUC 并发编程学习(3)

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


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

1.1 函数式接口

@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(消费者类的函数式接口)

在这里插入图片描述

(1)Function函数式接口

Function函数式接口,有一个输入参数,有一个输出。只要是函数式接口,可以用Lambda表达式简化。

public class Demo01 {
    public static void main(String[] args) {
        Function function = new Function<String,String>() {
            @Override
            public String apply(String o) {
                return o;
            }
        };
        System.out.println(function.apply("adsad"));
    }
}

Lambda:

public class Demo01 {
    public static void main(String[] args) {
        Function<String,String> function = (str)->{return str;};
        System.out.println(function.apply("adsad"));
    }
}

(2)Predicate 断定型接口

Predicate 断定型接口,有一个参数,返回值只能是布尔值

public class Demo02 {
    public static void main(String[] args) {
        Predicate<String> predicate = new Predicate<String>() {
            @Override
            public boolean test(String str) {
                return str.isEmpty();
            }
        };
     
        System.out.println(predicate.test("123"));
    }
}

Lambda:

public class Demo02 {
    public static void main(String[] args) {
        Predicate<String> predicate = (str)->{
            return str.isEmpty();
        };
        System.out.println(predicate.test("123"));
    }
}

(3)Consumer 消费型接口

Consumer 消费型接口:只有输入,没有返回值

public class Demo03 {
    public static void main(String[] args) {
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String o) {
                System.out.println(o);
            }
        };
        consumer.accept("123");
    }
}

Lambda:

public class Demo03 {
    public static void main(String[] args) {
        Consumer<String> consumer = (str)->{
            System.out.println(str);
        };
        consumer.accept("123");
    }
}

(4)Supplier 供给型接口

Consumer 消费型接口:没有参数,只有返回值

public class Demo04 {
    public static void main(String[] args) {
        Supplier<String> supplier = new Supplier<String>() {
            @Override
            public String get() {
                return "ad";
            }
        };
        System.out.println(supplier.get());
    }
}

Lambda:

public class Demo03 {
    public static void main(String[] args) {
        Consumer<String> consumer = (str)->{
            System.out.println(str);
        };
        consumer.accept("123");
    }
}

2. Stream流式计算


大数据:存储+计算。
存储:集合、MySQL。
计算:都应该交给流来操作。
在这里插入图片描述


public class User {


    public static void main(String[] args) {
        UserData a = new UserData(1, "a", 21);
        UserData b = new UserData(2, "b", 22);
        UserData c = new UserData(3, "c", 23);
        UserData d = new UserData(4, "d", 24);
        UserData e = new UserData(6, "e", 25);

        // 集合就是存储
        List<UserData> lis = Arrays.asList(a, b, c, d, e);
        // 计算交给流 链式编程
        lis.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);
    }
}
class UserData{
    private int id;
    private String name;
    private int age;
    public UserData(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserData{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3. ForkJoin 分支合并


ForkJoin 在1.7之后出现的,并行执行任务!提高效率。大数据量!
大数据:Map Reduce(大任务拆分为小任务)
在这里插入图片描述
ForkJoin特点:工作窃取

这里面维护的都是双端队列。
在这里插入图片描述

public class Demo01 extends RecursiveTask<Long> {
    private long start;
    private long end;
    // 临界值
    private long temp = 1000L;
    public Demo01(long start, long end) {
        this.start = start;
        this.end = end;
    }
    public static void main(String[] args) {
    }
    @Override
    protected Long compute() {

        if((end - start) < temp){
            Long sum = 0L;
            for (Long i = start; i < end; i++) {
                sum+=i;
            }
            return sum;
        }else{
            long middle = (start + end) /2;
            Demo01 demo01 = new Demo01(start, middle);
            demo01.fork(); // 拆分任务,把任务压入线程队列
            Demo01 demo02 = new Demo01(middle+1, end);
            demo02.fork(); // 拆分任务,把任务压入线程队列

            long l = demo01.join() + demo02.join();
            return  l;
        }
    }
}

测试类:

public class Test1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test3();
    }

    // 普通程序员
    public static void test1(){
        long start = System.currentTimeMillis();
        Long sum = 0L;
        for (Long i = 0L; i < 10_1001_1010; i++) {
            sum+=i;
        }
        long end = System.currentTimeMillis();
        System.out.println("时间"+(end-start)+",sum="+sum);
    }

    // 使用ForkJoin
    public static void test2() throws ExecutionException, InterruptedException {
        long start = System.currentTimeMillis();
        Long sum = 0L;
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        Demo01 demo01 = new Demo01(0L,10_1001_1010);
        ForkJoinTask<Long> submit = forkJoinPool.submit(demo01);// 提交任务
        Long aLong = submit.get();
        long end = System.currentTimeMillis();
        System.out.println("时间"+(end-start)+",sum="+aLong);
    }

    // Stream 并行流
    public static void test3(){
        long start = System.currentTimeMillis();
        long sum = LongStream.rangeClosed(0L, 10_0000_0000).parallel().reduce(0, Long::sum);
        long end = System.currentTimeMillis();
        System.out.println("时间"+(end-start)+",sum="+sum);
    }
}

4. Future异步回调


Future 设计的初衷:对将来的某个事件的结果进行建模

Future 实现类

在这里插入图片描述

(1)没有返回值的异步回调

public class Demo01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"");
        });
        System.out.println("1111111");
        Void unused = completableFuture.get(); // 阻塞获取执行结果
        System.out.println(unused);

    }
}

(2)有返回值的异步回调

public class Demo01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        CompletableFuture<Object> uCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName()+"");
            return 1/0;
        });
        Object s = uCompletableFuture.whenComplete((t, u) -> {
            System.out.println("t=>"+t);
            System.out.println("u=>"+u);
        }).exceptionally((f) -> {
            f.printStackTrace();
            return "233";
        }).get();
        System.out.println(s);
    }
}

5. JMM


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值