AtomicBoolean并行版本不起作用 - 但代理版本

时间:2016-12-01 23:56:16

标签: parallel-processing atomic agent gpars

我有一种方法,我尝试使用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聚合值的代理的版本似乎正在运行

非常感谢知道为什么原子布尔不起作用,提前谢谢

1 个答案:

答案 0 :(得分:0)

嗯,这是你如何使用AtomicBoolean的一个问题。你总是用force(getAndSet())覆盖存储在其中的值,并忽略当前线程忙于“评估”时其他线程可能已经改变它的可能性。

您可能想要使用compareAndSet()方法:

    def valueToUse = result.get()
    result.compareAndSet(valueToUse, valueToUse && condition.evaluate())