我有一种方法,我尝试使用GPARS并行计算并计算聚合布尔值'和'调用结果。此方法被包装为@ActiveObject,它将结果作为数据流传递 - 下面的代码具有原始方法,我尝试使用AtomicBoolean存储聚合来保护它。
这个没有工作(有时我的测试会通过其他人,他们会失败)计算的最终真相' 。为了解决这个问题,我从AtomicBoolean更改为Agent(布尔)方法,我认为它已经修复了'它 - 至少我的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
}
我把调试println放在这里只是为了让我看到代码在做什么
具有保护bool聚合值的代理的版本似乎正在运行
非常感谢知道为什么原子布尔不起作用,提前谢谢
答案 0 :(得分:0)
嗯,这是你如何使用AtomicBoolean的一个问题。你总是用force(getAndSet())覆盖存储在其中的值,并忽略当前线程忙于“评估”时其他线程可能已经改变它的可能性。
您可能想要使用compareAndSet()方法:
def valueToUse = result.get()
result.compareAndSet(valueToUse, valueToUse && condition.evaluate())