• 袁阳
    2019-04-23
    思考题:
    1,读数据库属于io操作,应该放在单独线程池,避免线程饥饿
    2,异常未处理

    作者回复: 👍👍

    
     34
  • 刘晓林
    2019-04-23
    思考题:
    1.没有进行异常处理,
    2.要指定专门的线程池做数据库查询
    3.如果检查和查询都比较耗时,那么应该像之前的对账系统一样,采用生产者和消费者模式,让上一次的检查和下一次的查询并行起来。

    另外,老师把javadoc里那一堆那一堆方法进行了分类,分成串行、并行、AND聚合、OR聚合,简直太棒了,一下子就把这些方法纳入到一个完整的结构体系里了。简直棒
    展开

    作者回复: 思考题考虑的很全面👍

    
     27
  • 密码123456
    2019-04-23
    我在想一个问题,明明是串行过程,直接写就可以了。为什么还要用异步去实现串行?

    作者回复: 这个简单场景没必要用

    
     17
  • 青莲
    2019-04-23
    1.查数据库属于io操作,用定制线程池
    2.查出来的结果做为下一步处理的条件,若结果为空呢,没有对应处理
    3.缺少异常处理机制

    作者回复: 👍👍

    
     10
  • 发条橙子 。
    2019-04-24
    老师 ,我有个疑问。 completableFuture 中各种关系(并行、串行、聚合),实际上就覆盖了各种需求场景。 例如 : 线程A 等待 线程B 或者 线程C 等待 线程A和B 。

    我们之前讲的并发包里面 countdownLatch , 或者 threadPoolExecutor 和future 就是来解决这些关系场景的 , 那有了 completableFuture 这个类 ,是不是以后有需求都优先考虑用 completableFuture ?感觉这个类就可以解决前面所讲的类的问题了

    作者回复: 我觉得可以优先使用CompletableFuture,当然前提是你的jdk是1.8

    
     7
  • 刘晓林
    2019-04-23
    我觉得既然都讲到CompletableFuture了,老师是不是有必要不一章ForkJoinPool呀?毕竟,ForkJoinPool和ThreadPoolExecutor还是有很多不一样的。谢谢老师

    作者回复: 后面有介绍

    
     5
  • Chocolate
    2019-04-23
    回答「密码123456」:CompletableFuture 在执行的过程中可以不阻塞主线程,支持 runAsync、anyOf、allOf 等操作,等某个时间点需要异步执行的结果时再阻塞获取。

    作者回复: 是的,复杂场景就能体现出优势了

     2
     4
  • Monday
    2019-12-23
    CompletableFuture从来没玩过,老师在工作/实践中有使用过这个类吗?

    作者回复: 用过,配合lambda效果很好

    
     3
  • Michael
    2019-05-23
    老师 你好,对文章点赞这种功能异步如何实现?

    作者回复: 喊一嗓子,让朋友点

    
     3
  • 圆滚滚
    2019-12-08
    老师,我看demo都是combine2个的,聚合多个的话怎么处理
     1
     2
  • 笃行之
    2019-04-29
    ”如果所有 CompletableFuture 共享一个线程池,那么一旦有任务执行一些很慢的 I/O 操作,就会导致线程池中所有线程都阻塞在 I/O 操作上,从而造成线程饥饿,进而影响整个系统的性能。”老师,阻塞在io上和是不是在一个线程池没关系吧?

    作者回复: 有关系,如果系统就一个线程池,里面的线程都阻塞在io上,那么系统其他的任务都需要等待。如果其他任务有自己的线程池,就没有问题。

     1
     2
  • 放个屁臭到了自己
    2019-11-21
    如果所有 CompletableFuture 共享一个线程池,那么一旦有任务执行一些很慢的 I/O 操作,就会导致线程池中所有线程都阻塞在 I/O 操作上


    这个是不是有问题?因为线程池有多个线程,如果只有一个阻塞,那么其他的线程也是可以的吧

    作者回复: 可以,实际情况不会只提交一个慢的任务

     1
     1
  • 佑儿
    2019-05-10
    带有asyn的方法是异步执行,这里的异步是不在当前线程中执行? 比较困惑

    作者回复: 不是在调用方法的线程中执行的,这样是不是更容易理解

    
     1
  • gogo
    2019-04-25
    1.我只是感觉到异常没处理

    2.没考虑到io动作需要定制线程去处理

    java异步编程看起来很有意思……
    
     1
  • henry
    2019-04-24
    老师我现在有个任务,和您的例子有相似的地方,是从一个库里查询多张表的数据同步到另外一个库,就有双重for循环,最外层用与多张表的遍历,内层的for循环用于批量读取某一张表的数据,因为数据量可能在几万条,我想分批次读出来再同步到另一个数据库,昨天写的时候用的是futuretask,今天正好看到老师的文章就改成了CompletableFuture,还没有用异常处理的,后面我还要看看怎么加上异常处理的。其它的不知道我用的对不对,请老师看看:
       // 初始化异步工具类,分别异步执行2个任务
            CompletableFuture<List<PBSEnergyData>> asyncAquirePBSEnergyData = new CompletableFuture();
            CompletableFuture<List<AXEEnergyData>> asyncSaveAxeEnergyData = new CompletableFuture();
            // 初始化两个线程池, 分别用于2个任务 ,1个任务一个线程池,互不干扰
            Executor aquirePBSEnergyDataExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            Executor saveAxeEnergyDataExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            queryUtils.getTableNames().forEach(tableName -> {
                int pageSize = queryUtils.getPageSize();
                //查询该表有多少条数据,每${pageSize}条一次
                int count = pbsEnergyService.getCount(tableName);
                //总页数
                int pages = count / pageSize;
                int pageNum = 0;
                final int pageNo = pageNum;
                for(pageNum = 0; pageNum <= pages; pageNum++){
                    // 异步获取PBS数据库的数据并返回结果
                    asyncAquirePBSEnergyData
                            .supplyAsync(() -> {
                        查询数据库
                        return pbsEnergyDatas;
                    },aquirePBSEnergyDataExecutor)
                            // 任务2任务1,任务1返回的结果
                            .thenApply(pbsEnergyDatas -> asyncSaveAxeEnergyData.runAsync(()->{
                        List<AXEEnergyData> axeEnergyDatas = pbsEnergyDatas.stream().map(pbsEnergyData -> {
                            //进行类型转换
                        }).collect(Collectors.toList());
                        //批量保存
                    },saveAxeEnergyDataExecutor));
                }
            });
    全部贴上去,超过字符数了,只能请老师凑合看了 :(
    展开

    作者回复: 有个地方需要注意:runAsync和supplyAsync都是静态方法。
    线程池设置的太小了,这是个IO密集型的任务
    thenApply里面的runAsync我觉得好像是没有必要,增加了复杂的了。

    如果thenApply里面需要异步,可以用thenApplyAsync

    
     1
  • 易儿易
    2019-04-23
    老师我有一个问题:在描述串行关系时,为什么参数没有other?这让我觉得并不是在描述两个子任务的串行关系,而是给第一个子任务追加了一个类似“回调方法”fn等……而并行关系和汇聚关系则很明确的出现了other……

    作者回复: 你也可以理解成给第一个子任务追加了一个类似“回调方法”。回调不也是在第一个任务执行完才回调吗?所以也是串行的。都是一回事,你怎么理解起来顺手就怎么理解就可以了。

    
     1
  • linqw
    2019-04-23
    课后习题,规则校验依赖于数据库中的规则,如果规则不是共用的,直接放在一个内部,如果规则是共用,可以在主线程进行规则获取,异步校验规则。thenApply会重新创建一个CompletableFuture
    PurchersOrder po;
    CompletableFuture<Boolean> cf =
      CompletableFuture.supplyAsync(()->{
        // 在数据库中查询规则
        r = findRuleByJdbc();
        // 规则校验
        return check(po, r);
      });
    Boolean isOk = cf.join();
    CompletableFuture的写法和rxjava的使用很类似,一个结果作为下一个的参数,链式操作等
    展开
    
     1
  • 木木匠
    2019-04-23
    我觉得课后思考题中,既然是先查规则再校验,这本来就是一个串行化的动作,为什么要异步呢?用异步的意义在哪?
    
     1
  • 江楠大盗
    2019-12-17
    王老师好,其他地方看到说异步 IO 主要是为了控制线程数量,请问怎么理解?

    作者回复: 目前的上下文,我也理解不了😂

    
    
  • Sharry
    2019-09-24
    是的, RxJava 已经是 Android 开发者必不可少的一个库了
    
    
我们在线,来聊聊吧