Java并发编程

JAVA异步编程

java 5前时代

并发实现

  • Java Green Thread
  • Java Native Thread

编程模型

  • Thread

  • Runnable

    使用join()实现线程同步

实现局限性

  • 缺少线程管理的原生支持
  • 缺少"锁"API
  • 缺少知悉选哪个完成的原生支持
  • 执行结果获取困难
  • Double Check Locking 不确定性
public class BeforeJava5 {

    public static void main(String[] args) throws InterruptedException {
        // 创建线程
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.printf("当前线程 Thread:%s, hello world...\n",Thread.currentThread().getName());
            }
        });
        // 启动线程
        thread.start();
        // 串行化操作
        thread.join();
        System.out.printf("当前线程 Thread:%s, start...\n",Thread.currentThread().getName());
    }

}

java 5时代

并发框架

  • J.U.C = java.util.concurrent

并发编程模型

  • Executor
  • Runnable、Callable
  • Future

java 7时代

并行框架

  • Fork/join

编程模型

  • ForkJoinPool
  • ForkJoinTask
  • RescursiveAction

FUture的限制

  • 无法手动完成
  • 阻塞式结果返回
  • 无法链式多个Future
  • 无法合并多个Future结果
  • 缺少异常处理
public class ForkJoinDemo1 {
    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        // 分为 Runnable 和 Callable, 前者无返回值,后者有
        Future<String> future = forkJoinPool.submit(new Callable() {
            @Override
            public Object call() throws Exception {
                return "hello world";
            }
        });
        String value = future.get();
        System.out.println(value);
    }
}
public class ForkJoinDemo2 {
    public static void main(String[] args) {
        /** 4核 **/
        System.out.printf("当前公用 ForkJoin 线程池 并行数:%d\n",ForkJoinPool.commonPool().getParallelism());
        System.out.printf("当前CPU 处理器数:%d\n",Runtime.getRuntime().availableProcessors());
        // 创建线程池
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        AtomicInteger atomicInteger = new AtomicInteger();
        // 创建task实现
        RecursiveAction recursiveAction = new Task(integers, atomicInteger);
        //提交并执行
        forkJoinPool.invoke(recursiveAction);
        // 关闭任务
        forkJoinPool.shutdown();
        System.out.println("运行结果: " + atomicInteger);

    }

    private static class Task extends RecursiveAction {

        private final List<Integer> integers;

        private final AtomicInteger atomicInteger;

        Task(List<Integer> integers, AtomicInteger atomicInteger) {
            this.integers = integers;
            this.atomicInteger = atomicInteger;
        }

        @Override
        protected void compute() {
            // 组装执行参数
            int size = integers.size();
            if (size >1){
                int part = size / 2;
                List<Integer> leftPart = integers.subList(0, part);
                Task task1 = new Task(leftPart, atomicInteger);
                List<Integer> rightPart = integers.subList(part, size);
                Task task2 = new Task(rightPart, atomicInteger);
                // fork/join  实现串行化
                invokeAll(task1,task2);
            }else {
                if (size == 0){
                    return;
                }
                Integer num = integers.get(0);
                //累加
                atomicInteger.addAndGet(num);
            }
        }
    }
}

Future 异步实现扩展

Netty Future

public class NettyFutureDemo {
   public static void main(String[] args) throws InterruptedException {

       System.out.println("netty future 异步实现开始...");
       long l = System.currentTimeMillis();

       // 初始化线程池
       EventExecutorGroup group = new DefaultEventExecutorGroup(4); // 4 threads
       Future<Integer> f = group.submit(new Callable<Integer>() {
           @Override
           public Integer call() throws Exception {
               System.err.println("执行耗时操作...");
               dealSomeThing();
               return 100;
           }
       });
       f.addListener(new FutureListener<Object>() {
           @Override
           public void operationComplete(Future<Object> objectFuture) throws Exception {
               System.err.println("计算结果::"+objectFuture.get());
           }
       });
       System.err.println("计算耗时:" + (System.currentTimeMillis() - l)+" ms");

       // 关闭线程池
       group.shutdownGracefully();
       System.out.println("netty future 异步实现结束...");
   }
   static void dealSomeThing() {
       try {
           Thread.sleep(3000);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

Guava Future

public class GuavaFutureDemo {

   public static void main(String[] args) throws InterruptedException {
       System.out.println("guava future 异步实现开始...");
       long l = System.currentTimeMillis();
       ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
       ListenableFuture<Integer> future = service.submit(new Callable<Integer>() {
           public Integer call() throws Exception {
               System.out.println("执行耗时操作...");
               dealSomeThing();
               return 100;
           }
       });
       Futures.addCallback(future, new FutureCallback<Integer>() {
           public void onSuccess(Integer result) {
               System.out.println("计算结果:" + result);
           }

           public void onFailure(Throwable throwable) {
               System.out.println("异步处理失败,e=" + throwable);
           }
       });
       System.out.println("算耗时:"+ (System.currentTimeMillis() - l)+" ms");
       System.out.println("guava future 异步实现结束...");

   }

   static void dealSomeThing() {
       try {
           Thread.sleep(3000);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

}

Future 有两种模式:将来式和回调式。而回调式会出现回调地狱的问题,由此衍生出了 Promise 模式来解决这个问题。这才是 Future 模式和 Promise 模式的相关性。

java 8时代

异步并行框架

  • Fork/join

编程模型

  • CompletionStage
  • CompletableFuture
  • 使用 CompletableFuture 解决回调地狱问题 (Callback Hell)
public class CompletableFutureDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 1. 完成操作可以被其他线程去做
//        CompletableFuture<String> completableFuture = new CompletableFuture<>();
//        completableFuture.complete("hello world");
//        String value = completableFuture.get();
//        System.out.printf("当前线程 Thread:%s,hello world...  %s\n",Thread.currentThread().getName(),value);

        // 2. 异步执行,阻塞操作
//        CompletableFuture runAsyncCompletableFuture = CompletableFuture.runAsync(()->{
//            String name = Thread.currentThread().getName();
//            System.out.println("Thread: " + name + " --hello world");
//        });
//        //保证执行顺序 hello world 输出在前  实际上还是阻塞主线程
//        runAsyncCompletableFuture.get();
//        System.out.println("staring...");

        // 3. 异步执行,非阻塞操作
//        CompletableFuture<String> supplyAsyncCompletableFuture = CompletableFuture.supplyAsync(()->{
//           // 假设是耗时操作 如:数据库查询
//            return String.format("当前线程 Thread:%s, hello world...\n",Thread.currentThread().getName());
//        });
//        String value = supplyAsyncCompletableFuture.get();
//        System.out.println("value = " + value);
//        System.out.println("staring...");

        // 4. 合并操作
        CompletableFuture  combainCompletableFuture = CompletableFuture.supplyAsync(()->{
            // 假设是耗时操作 如:数据库查询
            return String.format("当前线程 Thread:%s, hello world...\n",Thread.currentThread().getName());
        }).thenApply(value ->{
            return value + "数据库查询";
        }).thenApply(value ->{
            return value + LocalDate.now();
        }).thenApply(value ->{
            System.out.printf("当前线程 Thread:%s, hello world...\n",Thread.currentThread().getName());
            return value;
        }).thenRun(() ->{
            System.out.println("操作完成");
            throw new RuntimeException("抛一个异常");
            // Java 8 异常处理
        }).exceptionally(e -> {
            System.out.println(e);
            return null;
        });
        combainCompletableFuture.get();
        System.out.println("staring...");
        while (!combainCompletableFuture.isDone()){}
    }
}

spring 自身实现

主类:ListenableFuture

实现类:ListenableFutureTask

  • 主要实现部分代码
	private final Queue<SuccessCallback<? super T>> successCallbacks = new LinkedList<SuccessCallback<? super T>>();

public void addCallback(ListenableFutureCallback<? super T> callback) {
    Assert.notNull(callback, "'callback' must not be null");
    synchronized (this.mutex) {
        switch (this.state) {
            case NEW:
                this.successCallbacks.add(callback);
                this.failureCallbacks.add(callback);
                break;
            case SUCCESS:
                notifySuccess(callback);
                break;
            case FAILURE:
                notifyFailure(callback);
                break;
        }
    }
}

Reactive Streams

时代局限性(Java 9 之前)

  • 阻塞编程
    • 无法并行计算
    • 资源低效利用
  • 异步编程
    • Callback
    • Future

四种角色

  • Publisher:发布者
  • Subscriber:订阅者
  • Subscription:订阅的控制器
  • Processor:发布者|订阅者

Reactive Streams规范

对比Iterator模式

  • 数据方向
    • Reactive Streams: 推模式(Push)
    • Iterator:拉模式(Pull)
  • 编程模式
    • Reactive Streams:发布订阅模式(Publish-Subscriber)
    • Iterator:命令编程模式(Imperative)
  • 信号
    • onSubscribe():订阅事件
    • onNext():是数据到达事件‘
    • onComplete():订阅完成事件
    • onError:订阅异常
    • request():请求
    • cnacel():取消
  • 核心接口
    • Mono: 异步0-1元素序列,Future<Optional<?>>
    • Flux:异步0-N元素系列:Future<Collection<>>
  • 编程模式
    • 接口编程
    • 函数式编程
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值