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

final ではないローカル変数に基づいてジョブを送信しています。代わりに、次のことを試してください。

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必要な値が含まれます...

それがそれを説明することを願っていますか?

于 2013-08-05T13:27:27.980 に答える