0

我有这样的代码:

def updateSensor(List<String> boardIds, SensorShort sensor) {
    for (String boardId : boardIds) {
        println("Working on ${boardId} for ${sensor.sensorId}")
        pool.submit({
            println("[${Thread.currentThread().name}] Working on ${boardId} for ${sensor.sensorId}")

        })
    }
}

这段代码的结果是:

Working on 400 for 11
Working on 100 for 11
Working on 101 for 11
Working on 300 for 11

[pool-4-thread-4] Working on 300 for 11
[pool-4-thread-1] Working on 300 for 11
[pool-4-thread-3] Working on 300 for 11
[pool-3-thread-1] Working on 300 for 11

但这是错误的。它接缝 boardId 对象已被重写

4

1 回答 1

1

您正在提交基于非最终局部变量的作业,而是尝试:

def updateSensor(List<String> boardIds, SensorShort sensor) {
    boardIds.each { String boardId ->
        println("Working on ${boardId} for ${sensor.sensorId}")
        pool.submit {
            println("[${Thread.currentThread().name}] Working on ${boardId} for ${sensor.sensorId}")
        }
    }
}

原始代码的问题在于,当在单独的线程上评估闭包时,循环已经完成,并且局部boardId变量具有列表中最后一项的值。因此,每个作业都使用最后一个元素运行,而不是您需要的元素。

在 Java 中,您将声明(实际上,Java 会强制您将变量声明为final):

for( final String boardId : boardIds ) {

但是,groovy 没有局部最终变量:-/

通过使用,闭包内boardIds.each的局部boardId变量具有您需要的值...each

希望能解释一下?

于 2013-08-05T13:27:27.980 回答