我有这样的代码:
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对象已被重写
答案 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
变量具有您需要的值...
希望能解释一下吗?