【问题标题】:Execute method with a return type and input parameter in parallel并行执行具有返回类型和输入参数的方法
【发布时间】:2020-09-23 12:01:31
【问题描述】:

我有以下代码。在执行 m1 和 m2 时,我想通过 3 个线程并行执行 m3()

我怎样才能实现它。我正在使用 Spring Boot 和 java 8。是否可以使用执行器服务执行 m3()

@Service
class Main {
    @Autowired
    Private Other other;
    ExecutorService executorService = Executors.newFixedThreadPool(3);
   
    void test_method() {
        for (int i = 0; i < 201; i++) {
            executorService.submit(() -> other.m1()); // works fine as expected 
            executorService.submit(() -> other.m2()); // works fine as expected 
            executorService.submit(() -> other.m3(i)); // compilation error  as expected
    }
}

错误是

我在封闭范围内定义的局部变量必须是最终的或 有效地最终

方法如下

@Service
class Other {
    void m1() {
    }
    
    String m2() {
        return "Hello";
    }
 
    int m3(int n) {
        return n;
    }
}

【问题讨论】:

  • 错误是什么?
  • Local variable i defined in an enclosing scope must be final or effectively final

标签: java spring multithreading spring-boot parallel-processing


【解决方案1】:

在 Java 中,您不能在匿名内部类中使用非最终变量,例如 lambda 表达式。

  • final 变量是一个只被实例化一次的变量。
  • 有效最终变量是指其值在初始化后永远不会改变的变量。

一种可能的解决方法是使用IntStream.rangeIntStream.forEach 方法:

IntStream.range(0, 201).forEach(i -> {
    executorService.submit(() -> other.m1());
    executorService.submit(() -> other.m2());
    executorService.submit(() -> other.m3(i));
});

【讨论】:

  • 谢谢。但是你的方法适用于 int。假设我将一些自定义 Pojo 像 MyObject 传递给 m3() 那么我该怎么做呢?有什么优雅的方法吗?
  • 魔法循环有效:for (Pojo pojo: list) { executorService.submit(() -&gt; other.m3(pojo)); }
【解决方案2】:

试试这个:

void test_method() {
    for (int i = 0; i < 201; i++) {
        executorService.submit(other::m1);
        executorService.submit(other::m2);
        final int i1 = i;
        executorService.submit(() -> other.m3(i1));        
    }
}

【讨论】:

  • 我会尝试谢谢。我通过使用为 int final MyContainer myContainer = new MyContainer(i); myContainer.getIntValue() 创建一个容器类解决了这个问题。但是你有什么优雅的解决方案可以在没有 ExecutorService 的情况下与 ot 并行执行 m3()跨度>
  • 你和我的解决方案几乎相同。但假设我将一些自定义 Pojo 类传递给 m3
  • @PaleBlueDot 与什么并行执行 m3()?它已经以最大可能的逻辑并行性执行。要实现最大的物理并行性,请使用 ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多