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

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

  •  
  •   unregister · 233 天前 · 1857 次点击
    这是一个创建于 233 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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