对象已被重写在循环中

时间:2013-08-05 13:24:16

标签: groovy

我有这样的代码:

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对象已被重写

1 个答案:

答案 0 :(得分: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}")
        }
    }
}

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

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

for( final String boardId : boardIds ) {

但是,groovy没有本地最终变量: - /

通过boardIds.each执行此操作,boardId闭包内的本地each变量具有您需要的值...

希望能解释一下吗?