【问题标题】:Multithreading for array in JavaJava中数组的多线程
【发布时间】:2017-09-11 13:21:12
【问题描述】:

所以,场景是这样的:

//Some code...

public Map<String, String> someFunction() {
    for (final UserDetail user : userDetailList) {
        // the following (below) code runs in background thread
        // long running task
        new RecordPersonalisedDao().getPendingRecordsForUid(user.getuId(), new RecordPersonalisedDao.OnResultFetched() {
            @Override
            public void onResult(Result result) {
                // callback after the user is processed
                // put some parameter from result to map
                map.put(user.getName(), result.getTotal());
            }
        });
    }
    // return map only after all users are processed
    return map;
}

正如上面这段代码的注释中提到的,我希望只有在处理完整个用户列表后才返回最终的地图。

我无法更改RecordPersonalisedDao#getPendingRecordsForUid 的功能,使其仅在主线程中运行。

如何在 java 中实现这一点?

编辑:这种类型的问题通常会遇到。所以,我想了解java中相同的解决方案。

简单地说,我想要这样的行为

  • 在后台为数组中的所有成员运行此代码,完成后,发送回调。

(大概)

[list_of_some_data]
    .forEach( run this function )
    .after(after the function is run in background for  all members of list - return some value)

【问题讨论】:

  • thread safe map for java的可能重复
  • 使用join()方法等待后台线程完成。
  • 你想要的是一个 ExecutorService 并使用提交任务返回的 Future 作为你的回调。
  • 如果我理解正确,那么您想使用Future 并使用CompletableFuture.allOf 以等待所有Futures。见这里stackoverflow.com/a/36261808/3883957

标签: java multithreading java-threads


【解决方案1】:

在循环之前,创建一个计数等于用户列表长度的CountdownLatch。在结果处理程序中,更新地图后倒计时。 loopawait()之后的锁存器要倒计时,然后返回。

【讨论】:

  • 真正的问题是如何并行处理。我真的不明白你的“答案”是如何回答的。不要误会我的意思......但我猜你没有通过给出这样的答案来收集你的 200K 声誉,是吗?
  • @GhostCat 问题非常清楚地表明getPendingRecordsForUid() 在后台线程中运行,并且更一般地说,问题是如何阻塞直到所有后台任务都完成 - 在您可以'不要改变任务本身。
  • 例如,“以下(以下)代码在后台线程中运行”,“我无法更改 RecordPersonalisedDao#getPendingRecordsForUid 的功能以使其仅在主线程中运行”和“返回映射只有在所有用户都被处理后”
  • 谢谢先生 :) 使用CountDownLatch 解决了同样的问题。
【解决方案2】:
public Map<String, String> someFunction() {
    CountDownLatch cdl = new CountDownLatch(userDetailsList.size());
    for (final UserDetail user : userDetailList) {
        // the following (below) code runs in background thread
        // long running task
        new RecordPersonalisedDao().getPendingRecordsForUid(user.getuId(), new RecordPersonalisedDao.OnResultFetched() {
            @Override
            public void onResult(Result result) {
                // callback after the user is processed
                // put some parameter from result to map
                map.put(user.getName(), result.getTotal());

                //We're done grabbing the results.. count down.
                cdl.countDown();
            }
        });
    }

    //Block this thread until all the results are in.
    cdl.await();

    return map;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    相关资源
    最近更新 更多