【问题标题】:Java Parallel Network Requests and List UpdatesJava 并行网络请求和列表更新
【发布时间】:2017-01-30 01:12:19
【问题描述】:

我仅限于 AWS 上的 1 核机器,但在测量完成我的所有 http 请求并检查其结果的时间后,其中两个加起来需要与其余 50 个请求一样多的时间来获取数据(大约 2 分钟)。

我不想让我的代码过于臃肿,但我知道并行性和异步性会严重缩短此任务的执行时间。我想在它们自己的线程上启动两个大请求,这样它们就可以在其他线程运行时发出,但我目前将这些 http 请求的结果存储在一个列表中。

只要预先初始化数据,您能否同时访问列表的不同(保证)元素?我见过并发列表和并行列表,但一个不是并行的,另一个在每次修改时重新分配整个列表,所以这两者都不是一个特别明智的选择。

在这种情况下我该怎么办?

【问题讨论】:

  • 您可以创建自己的线程,然后将您的请求列表分派到不同的线程吗?
  • 我试过了,得到了一个非常有趣的结果。我有 3 个数据集。如果我设置一个 Thread[] team = new Thread[dataSets.length];然后让它们全部旋转,整体吞吐量要高得多,但即使在做了 for(int I=0; I
  • 将列表条目设置为结果数组的索引在线程内也仍然正确,但始终失败。在线程死亡的过程中是否发生了某种延迟以将结果提交回来?
  • 我发现 Thread.isAlive() 方法没用。它只是告诉您它当前是否处于活动状态,而不是它是否已退役。如果我遍历线程团队并只使用 thread.join(),突然间所有数据都会正确更新。为什么是这样?方法的名称与它完成的任务无关。

标签: java multithreading parallel-processing network-programming


【解决方案1】:

Java 中没有并发列表这样的东西。我假设您指的是并发哈希集(使用newSetFromMap),而您的“并行列表”指的是CopyOnWriteArrayList

您绝对可以使用前一个选项来存储更新数据。

解决异步更新数据问题的更好方法是简单地为您的工作线程使用非线程安全集合,然后在完成后将它们全部推送到您的线程安全集合用于汇总您的所有请求。

比如:

Set<Response> aggregate = Collections.newSetFromMap(...);
executor.execute(...);
...

// Workers
Set<Response> local = new HashSet<>();
populate(local);

aggregate.addAll(local);

如果您希望以特定方式对响应数据进行排序,例如将来自请求 1 的所有响应放在一起,您可能需要使用各种同步器。如果您只需要移动每个工作人员的一个请求,请使用线程安全传输或单例集合。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多