这个异步调用在我的例子中是如何工作的

时间:2018-03-05 11:08:43

标签: java asynchronous callback

我学习Java并想知道这段代码中是否item

useResult(result, item);

将来自

的下一个电话会覆盖
doItem(item);

这是eaxmple:

public void doSomeStuff() {
        //  List with 100 items
        for (Item item : list) {
            doItem(item);
        }
    }

    private void doItem(final Item item) {
        someAsyncCall(item, new SomeCallback() {
            @Override
            public void onSuccess(final Result result) {
                useResult(result, item);
            }
        });
    }

SomeCallback()在未来的某个时间发生,它是另一个线程

我的意思是当回调返回时useResult(result, item); item是否相同?

请告知这里发生了什么?

1 个答案:

答案 0 :(得分:1)

  

我的意思是回调返回时useResult(result, item);项是否相同?

当然会有什么效果呢?

您正在做的是创建100个不同的 SomeCallback类,这些类将处理不同的Item对象。

someAsyncCall的骨架可能如下所示:

public static void someAsyncCall(Item i, Callback callback) {
    CompletableFuture.runAsync( () -> { // new thread
        Result result = computeResult(i);
        callback.onSuccess(result, i);
    });
}

重点是:Callback,在实例化的那一刻,我不知道他将作为参数得到的Item。只有在将来执行Callback::onSuccess时,他才会知道它。

那么,Item i会改变(被分配一个新对象)吗?

不,因为final内的有效 someAsyncCall(对象值未明确更改)。

您甚至无法分配i = new Item(),因为编译器会抱怨访问non-final变量的匿名函数。

您当然可以创建一个新的Item并将其传递给回调

Item i2 = new Item();
callback.onSuccess(result, i2);

然后它会成为一个令人讨厌的图书馆的地狱......

除非您的i.setText("bla")班级为Result(成员字段为immutable),否则没有人禁止您final

修改

如果您的问题是java如何处理方法参数中的对象,那么答案是:,它们只是原始实例的副本。

您可以尝试使用简单的交换方法void swap(Item i1, Item 12);,并且您会注意到引用仅在函数内有效交换,但是一旦返回,对象将分别指向其原始实例。

但它是反映原始实例的副本。

回到你的榜样。想象一下,someAsyncCall在执行回调之前等待10000毫秒。

在您致电for loop之后,在doItem

,您还可以:item.setText("bla");

当您在item.getName()内打印useResult时,您将获得bla。即使在调用异步函数后文本已更改。