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

在ExecutorService中提交任务时设置变量值[重复]

田俊爽
2023-03-14

使用ExecutorService,我提交了一批任务,任务有一个时间变量,即general_time之间的共享。我想在提交任务之前设置general_time的值。代码如下:

ExecutorService executor = Executors.newWorkStealingPool();
    ArrayList<Callable<Boolean>> callables = new ArrayList<>();
    long GENERAL_TIME = 0;
    for (String i : host.getHosts()){
        callables.add(
                () -> {
                    ESBRun.monitorOSMetrics(
                            db, COMPONNENT_TYPE, GENERAL_TIME, metric, ssh, i
                    );
                    return true;
                }
    }
    GENERAL_TIME = System.currentTimeMillis();
    executor.invokeAll(callables)
            .stream()
            .map(future -> {
                try {
                    return future.get();
                }
                catch (Exception e) {
                    throw new IllegalStateException(e);
                }
            });
}

但它出错了

variable used in lambda should be final or effectively final java

我该怎么解决?

共有1个答案

齐献
2023-03-14

您的变量定义在堆栈上,该堆栈通常在方法退出后进行垃圾回收。然而,使用lambda中的值需要Java在闭包中共享值,这要求它是final或实际上是final(不被共享给它的任何代码修改)。因此,任何要在线程间保持可变的值都必须包装到一个实例中,该实例本身是final或实际上是final。

实现这一点的最简单且线程安全的方法是使用java.util.concurrent.Atomic中的类,在您的例子中是atomiclong。变量本身实际上是final,或者可以声明为final,但是可以在任何lambda和线程中设置(和读取)该值:

// declaration
final AtomicLong generalTime = new AtomicLong(0);

// usage acr
generalTime.set(System.currentTimeMillis()));
generalTime.get();
 类似资料:
  • 要并行或异步运行一些东西,我可以使用ExecutorService:

  • 我正在尝试将一个任务提交给Java的ExecutorService。它要么需要一个Callable,它允许抛出异常,要么需要一个Runnable。我的用例是愚蠢的:我想安排一个抛出异常的任务,但它是一个无效的方法。因此,我不能使用Callable或Runnable,因为方法定义与我的用例不匹配。我还想让我的异常从提交后收到的Future传播。有什么想法吗?

  • > 在将所有内容提交给后, 在上调用 则在shutdown()之前提交的所有任务都实际完成运行之前,awaitTermination()才返回。--然后在上调用,但是由于提交给的所有任务都已完成,并且从上的任务中提交给的所有任务都已提交给,所以在上调用之前,所有任务都已提交给。--对于以此类推 但是,我现在添加了这样一种情况,即可以将datapacket分解成一个较小的包,并在上提交额外的任务,而

  • 我将可调用任务(使用submit())提交给ExecutionService的实现。有时我似乎遇到了死锁,但无法工作在哪里或为什么会发生,所以我想为任务设置一个超时,我不清楚是如何做到的? 我应该吗 在提交任务时,在ExecutionService上使用invokeAny()而不是submit()并设置超时。我使用submit()一次提交许多任务,我是否也可以这样使用invokeAny(),我很谨

  • 我想使用ExecutorService来运行一系列相同的可运行/可调用任务。我到处找了一个教程或示例,但没有涉及到实际设置现有Runnable/Callable对象的值,然后使用submit()将该对象发送回ExecutorService。 基本上,我想做的是: 获取服务器列表。 遍历服务器列表,调用获取每个主机上的数据。 将数据收集到服务器bean中以存储在数据库中。 所以,现在,有10,000

  • 问题内容: 我不熟悉Thymeleaf,并将Web页面从JSP转换为Thymeleaf。我有一个像这样的strut标签: 该变量可以在JSP中的任何地方使用。Thymeleaf中是否有其他替代方法? 问题答案: 你可以使用局部变量。 声明带有属性的HTML元素。例如 文档说明 当被处理时,该变量被创建为一个局部变量,并添加到变量地图从上下文来,所以它是可用于评估任何其他变量从一开始就在上下文中声明