У меня есть метод, в котором я пытался распараллелить вычисление с помощью GPARS и вычислить совокупный логический результат «И» для вызовов. Этот метод обернут как @ActiveObject, который доставит результат в виде потока данных — в приведенном ниже коде используется исходный подход, когда я пытался сохранить агрегат, используя AtomicBoolean для его защиты.
Это не сработало (иногда мои тесты проходили, другие не проходили) на расчетной «конечной истине». Чтобы исправить это, я перешел с AtomicBoolean на подход Agent (boolean), и я думаю, что это «исправлено» - по крайней мере, мои тесты spock постоянно успешны.
В чем была ошибка моей логики при попытке использовать AtomicBoolean для получения конечного результата? Казалось, что это должно работать, но не работает, и я не понимаю, почему.
Метод ниже - я поставил оригинальную версию, а исправленную версию ниже
@ActiveMethod
def evaluateAllAsync () {
AtomicBoolean result = new AtomicBoolean(true)
GParsPool.withPool {
// do as parallel
conditions.eachParallel { condition ->
println "evalAllAsync-parallel intermediate result start value is ${result.get()} and condition with expression ${condition.expression} evaluated to ${condition.evaluate()}"
result.getAndSet(result.get() && condition.evaluate())
println "recalc bool value is now ${result.get()}"
}
}
println "evalAllAsync-parallel final result value is ${result.get()}"
result.get()
}
Исправлена проблема с использованием такой формы агента
@ActiveMethod
def evaluateAllAsync () {
def result = new Agent (true)
GParsPool.withPool {
// do as parallel
conditions.eachParallel { condition ->
println "evalAllAsync-parallel intermediate result start value is ${result.val} and condition with expression ${condition.expression} evaluated to ${condition.evaluate()}"
result << { def res = it && condition.evaluate(); println "start> $it and finish> $res"; updateValue(res)}
println "recalc bool value is now ${result.val}"
}
}
println "evalAllAsync-parallel final result value is ${result.val}"
result.val
}
Я поместил здесь debug println, чтобы видеть, что делает код.
Версия с агентом для защиты агрегированного значения bool работает.
Почему атомарное логическое значение не работает?