V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
unregister
V2EX  ›  Java

怎么使得异步方法执行完成然后在进行下一步。

  •  
  •   unregister · 2023-09-07 19:33:29 +08:00 · 2098 次点击
    这是一个创建于 441 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如有个方法 是 public void searchxx 那么里面调用了一个自己框架里的异步方法,没有返回值,另外的方法调用这个 search 方法的时候怎么等到它执行完之后,怎么把它变阻塞,才进行下一步?有没有大佬指点一下,比较简单的,不涉及到框架代码重写的,只能修改 search 方法

    第 1 条附言  ·  2023-09-07 22:43:10 +08:00
    感谢大家的留言,代码的话这次我就不贴出来了,我觉得#14 楼说的很形象,因为里面都直接调用封装好的东西,确实改不了。以后的话我也注意多积累这方面的知识,哈哈,点个♥️聊表谢意,哈哈。
    22 条回复    2023-09-11 08:27:18 +08:00
    lvxiaomao
        1
    lvxiaomao  
       2023-09-07 19:38:51 +08:00   ❤️ 1
    1 、如果要阻塞,那为啥 search 里面是异步执行?
    2 、异步使用 future 返回,future 等待结果完成 再做 search 的 return 呗
    wctml
        2
    wctml  
       2023-09-07 19:38:58 +08:00   ❤️ 1
    协程
    unregister
        3
    unregister  
    OP
       2023-09-07 19:40:36 +08:00
    @lvxiaomao 好的,谢谢大佬,我决定自己在网上找一下资料,在试试
    @wctml
    unregister
        4
    unregister  
    OP
       2023-09-07 19:40:48 +08:00
    @wctml 我们是 java 8 的
    mango88
        5
    mango88  
       2023-09-07 19:46:07 +08:00   ❤️ 1
    你框架里异步方法可以改吗
    minho
        6
    minho  
       2023-09-07 19:59:35 +08:00   ❤️ 1
    用 CountDownLatch 试试
    leonshaw
        7
    leonshaw  
       2023-09-07 20:05:28 +08:00 via Android   ❤️ 1
    异步方法完成是怎么通知的
    gosidealone
        8
    gosidealone  
       2023-09-07 20:09:40 +08:00   ❤️ 2
    CompletableFuture
    leeton
        9
    leeton  
       2023-09-07 20:31:05 +08:00 via iPhone   ❤️ 1
    我懂了你的意思,你调用了一个框架方法,它是异步的且没有返回值。你又不能修改框架方法,那就看看这个方法的参数能不能搞一个子类,弄一个 CountDownLatch 上去。
    leeton
        10
    leeton  
       2023-09-07 20:40:10 +08:00 via iPhone
    @leeton #9 尴尬了,框架方法里没法 countDown😅
    imokkkk
        11
    imokkkk  
       2023-09-07 20:53:39 +08:00   ❤️ 1
    CompletableFuture 感觉很好用 现在代码里异步基本都用它处理了 可以看下这篇文章
    https://mp.weixin.qq.com/s/GQGidprakfticYnbVYVYGQ
    kaneg
        12
    kaneg  
       2023-09-07 20:59:03 +08:00 via iPhone   ❤️ 1
    search 没有结果你怎么使用?还是把代码脱敏后贴上来大家才能帮你想办法,不然都是猜
    yolee599
        13
    yolee599  
       2023-09-07 21:11:01 +08:00 via Android   ❤️ 1
    创建一个信号量,执行语句之后就 take 这个信号量,注意 take 的超时间设为无限,这时候就会阻塞。在完成的回调里 give 信号量,这时候就会继续执行下去了。
    nothingistrue
        14
    nothingistrue  
       2023-09-07 21:29:08 +08:00   ❤️ 1
    如果异步方法本身未返回 Feture ,并且你还不能改它的话,放弃吧,无解。你不能期待一个吃草的狼。

    如果你的不能改,只是因为框架的限制,不能改方法的返回类型,但可以改方法体的话( 我猜你在用 Spring 的 @async ),最好的解决方案,还是换异步调用的方式,用 JDK 自带的就行,也费不了多少代码。
    CompletableFuture.runAsync(() ->{
    // 需要异步执行的东西,但这个方法内部,要是同步的,不要转向调用那个写好的异步方法
    }).XXX// 这里既有不阻塞的,也有阻塞的,名字忘了,自己找一下。

    极端情况下,连 JDK 自带的都用不了,比如你上面那个方法体中,还要再调用其他不返回 Feture 的异步方法,那就只能回滚最传统的方式了。弄个在第三方位置的标志数据,异步方法执行完成时修改标志,主方法调用异步方法后,轮询这个标志数据。但是这也有个前提,你得能改异步方法得执行体,不然就又回到第一段了。
    yazinnnn
        15
    yazinnnn  
       2023-09-07 22:17:51 +08:00
    传个回调....

    js 里会的东西到了 java 里就不会了吗......
    manhere
        16
    manhere  
       2023-09-07 22:42:47 +08:00
    简单粗暴引入一个 eventbus 完事
    superedlimited
        17
    superedlimited  
       2023-09-08 01:35:45 +08:00 via iPad
    java 的话用 rxjava
    listenerri
        18
    listenerri  
       2023-09-08 10:52:28 +08:00
    /**
    * 那就摆烂
    */
    sleep(20);
    baolinliu442k
        19
    baolinliu442k  
       2023-09-09 08:58:45 +08:00
    @listenerri 简单直接
    howfree
        20
    howfree  
       2023-09-09 14:06:19 +08:00
    @listenerri 俺这样做过,哈哈
    SoloCompany
        21
    SoloCompany  
       2023-09-09 21:15:36 +08:00
    还有一种上面没提到的方案, 就是 spawn 代替 call, 代价就是需要启动一个额外的进程来执行目标代码
    trzzzz
        22
    trzzzz  
       2023-09-11 08:27:18 +08:00 via iPhone
    要同步要异步有点矛盾。建议都用 CompletableFuture 包装,没有返回值直接用 thenRun
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   979 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 20:38 · PVG 04:38 · LAX 12:38 · JFK 15:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.