当前位置: 首页 > 知识库问答 >
问题:

并发填充列表中的经典for loop vs Arraylist forEach-Java 8

丌官盛
2023-03-14

我正在对数组列表使用Java8迭代器。假设我有一个futures的ArrayList,在使用经典的for循环和使用ArrayList foreach之间有什么问题/建议吗?(除了不能从lambda表达式中抛出异常之外)

假设未来主义者同时被填补,最好的方法是什么?最后一个foreach示例是否容易出现问题?

@Override
public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}
public void waitForCompletion(List<Future<HttpResponse>> futureList) {
    futureList.forEach(future -> {
        try {
            future.get();
        } catch (InterruptedException | ExecutionException e) {
            LOG.error("Something went wrong: ", e);
        }
    });
}
private void waitForCompletion(List<Future<HttpResponse>> futureList) {
    for(int i=0; i < futureList.size(); i++) {
        try {
            futureList.get(i).get();
        } catch (InterruptedException | ExecutionException e) {
            LOG.error("Something went wrong: ", e);
        }
    }
}
private void waitForCompletion(List<Future<HttpResponse>> futureList) {
    for(Future<HttpReponse> future:futureList) {
        try {
            future.get();
        } catch (InterruptedException | ExecutionException e) {
            LOG.error("Something went wrong: ", e);
        }
    }
}

共有1个答案

许涵容
2023-03-14

在您的示例中,可以只使用for-each循环:

private void waitForCompletion(List<Future<HttpResponse>> futureList) {
    for(Future<HttpReponse> future:futureList) {
        try {
            future.get();
        } catch (InterruptedException | ExecutionException e) {
            LOG.error("Something went wrong: ", e);
        }
    }
}

注意:ArrayList#Get不支持fail-fast特性,因此第二种方法与第一种方法不同。

fail-fast:如果在创建迭代器之后的任何时候以任何方式(除了通过迭代器自己的remove或add方法之外)对列表进行结构化修改,迭代器将抛出一个ConcurrentModificationException。因此,在面对并发修改时,迭代器会迅速而干净地失败,而不是冒着在未来某个未定时间任意、非确定性行为的风险。

List<Integer> list = new ArrayList<Integer>();
list.add(1);
Iterator<Integer> it = list.iterator();

it.next(); // return 1;

list.add(2);// the list is modified 
it.next();
// ^--- fail-fast throws a ConcurrentModificationException
private void waitForCompletion(List<Future<HttpResponse>> futureList)
                                                   throws Exception {
    for(Future<HttpReponse> future:futureList) {
         future.get();
    }
}

另一个不同的地方是数组#foreach只创建一次lambda表达式实例。但是for-each循环将为每个调用创建一个新的迭代器,例如:

void forEachLoop(){
  //          v--- create a new Iterator when forEachLoop was called.
  for(T item:items);
}

void forEach(){
                // v--- create a single lambda instance.
  items.forEach(it->{});
}
 类似资料:
  • 我有以下代码: 在其中,我想创建一个名为“”的新的”,其键与原始dict

  • 我是Laravel的新手。当我试图从表中填充下拉列表时,我有一个“找不到变量”的问题:表名称是猫(类别),模型名称是“猫”,看起来像这样: 一个项目可以有一个类别。类别名称可以位于多个项目中。我现在想在表格中填充一个下拉列表,在其中插入一个新项目:为了实现这一点, 我走了一条路线: 我在我的HomeController中创建了一个函数,在那里我将(我确实这样认为)变量$cat传递给我的视图: 或其

  • 我在SpringBoot中使用liquiBase 3.8.0。我的changelog文件树如下所示: 我尝试使用上下文,但发现了奇怪的行为--如果我在changelog-master.xml或changelog-test.xml中使用上下文,就像这样(父级changelog文件): 之后,contexts列将填充“!prod AND test” 我希望contexts列始终是填充的(如果我在父ch

  • 在SpringMVC项目的控制器中,我确实有一个列表,我将其放在模型映射中,如下所示。 现在我想在thymeleaf视图中使用post方法动态填充它。为此,我使用了一个JavaScript脚本。这不是所有的html代码,但为了简单起见,我只添加了JS部分。 这是测试有效的后方法。 它向我显示了错误:错误解析模板[],模板可能不存在或任何已配置的模板解析程序都无法访问,这肯定是因为:。有没有办法动态

  • 我正在制作一组自定义swing组件,这些组件实现各种属性,如标志或。我在尝试填充各种自定义组件的,然后根据每个组件的对列表进行排序时遇到问题。 我试图做到这一点的方法是让我的组件实现一个名为的接口,该接口实现一个方法。然后使用我的

  • 问题内容: 如何用对象类型的列表中的值填充JTable。我的代码如下所示: 我已经有了列,列表将来自schedule变量?考虑这些列,如何将其放到表中? 问题答案: 看一下DefaultTableModel。您可以遍历List并为每一行创建Object数组。