为了账号安全,请及时绑定邮箱和手机立即绑定

在Java中使用异步后,主方法如何返回异步中得到的值?

在Java中使用异步后,主方法如何返回异步中得到的值?

吃鸡游戏 2019-03-22 10:15:30
一个返回值为User的方法,在内部调用了异步方法(比如Rxjava,或者异步的网络请求),其内部匿名函数内才能拿到user对象,那么我的方法应该怎么return这个对象?
查看完整描述

7 回答

?
白板的微信

TA贡献1883条经验 获得超3个赞

方法的返回值为user,那这个方法就不能叫异步方法了。除非这个方法返回future,或者类似于可以在之后拿到结果的引用,这个方法才能叫异步方法。想调完方法后得到user,那么方法里面就没有必要再放置异步的代码了,一点意义都没有。


异步的返回结果只能通过回调。


同步的方法通常是这样的


public User syncGetUser() {

    User user = heavyWork();

    return user;

}

由于heavyWork方法可能需要查数据库,或者做大量计算,所以heavyWork方法会执行大量的时间。

如果你不想等待大量的时间,这时候异步就可以派上用场了。


public Future<User> asyncGetUser() {

    Future<User> future = threadPool.submit(new Callable<User> {

        public User call() throws Exception {

            return heavyWork();

        }

    }

    

    return future;

}

到了这里,heavyWork已经交给另外一个线程去跑了,并返回一个future给你。

之后,你可以通过这个future的get方法得到你想要的user。


这才是异步的意义和用处所在。题主的题目本身就是矛盾的。在一个含有异步代码的方法里面返回异步执行的结果,是个矛盾的事情。


查看完整回答
反对 回复 2019-04-24
?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

我没有研究过 RxJava,不过之前团队里面做 Android 的开发的同事说是很好用。


1 楼给了一种使用 Future 的方案,但是很抱歉 Future 是一种异步阻塞式的API,即没有通知回调。


至于回调怎么实现,这个应该很基本,去看看观察者模式就好了,本质还是利用接口的多态特性。


不过可以使用 google guava,里面提供了一种增强的 Future 为 ListenableFuture。


这里引用 1 楼的例子,进行修改。


 class A implements FutureCallback{

        ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

        ListenableFuture futrue = service.submit(new Callable() {

            public User call() {

                return heavyWork();

            }

        });

        Futures.addCallback(furtrue,this);


        public void onSuccess(User user) {

            //这个是回调执行的代码

        }

        public void onFailure(Throwable thrown) {


        }

    }


查看完整回答
反对 回复 2019-04-24
?
aluckdog

TA贡献1847条经验 获得超7个赞

异步方法的“返回”在执行代码之前。代码都还没执行,怎么返回结果?


查看完整回答
反对 回复 2019-04-24
?
冉冉说

TA贡献1877条经验 获得超1个赞

我觉得使用回调方式也可以


查看完整回答
反对 回复 2019-04-24
?
米脂

TA贡献1836条经验 获得超3个赞

使用CountDownLatch 可以将异步操作,转换为同步操作。

final CountDownLatch latch = new CountDownLatch(1);


调用异步方法。
在异步回调结果中,
latch.countDown();


然后
try {


latch.await();


} catch (InterruptedException e) {
 
}



return 数据;


查看完整回答
反对 回复 2019-04-24
?
精慕HU

TA贡献1845条经验 获得超8个赞

java里有线程返回Callable接口


查看完整回答
反对 回复 2019-04-24
  • 7 回答
  • 0 关注
  • 5285 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信