Groovy - GPars - Active Object - Active Method 返回一个值



在Groovy中,我需要实现一个名为MyCounter的ActiveObject实例,以便以下代码通过:

final MyCounter counter = new MyCounter()
counter.incrementBy 10
counter.incrementBy 20
counter.update 'Hello'
assert 35 == counter.value

我已经提供了下面列出的两个实现 - 它们都不起作用。

1.

@ActiveObject
class MyCounter
{
    private int counter = 0
    @ActiveMethod
    def incrementBy(int value)
    {
        println "incrementBy $value"
        counter += value;
    }
    @ActiveMethod
    def update(String value)
    {
        println "update $value"
        counter += value.size();
    }
    int getValue()
    {
        println "getValue"
        return counter;
    }
}

我想这不起作用,因为对incrementBy的调用不会阻塞,例如 value 属性,因此实际上在 incrementBy 操作完成之前访问了计数器变量。

阿拉伯数字。

@ActiveObject
class MyCounter
{
    private int counter = 0
    @ActiveMethod
    def incrementBy(int value)
    {
        println "incrementBy $value"
        counter += value;
    }
    @ActiveMethod
    def update(String value)
    {
        println "update $value"
        counter += value.size();
    }
    @ActiveMethod
    int value()
    {
        println "getValue"
        return counter;
    }
}

编译器告诉我:

非阻塞方法不得返回特定类型,而应使用 def 或 void

好的,基于这是 GPars 的假设,您应该能够使用以下代码使用您的第一个实现:

final MyCounter counter = new MyCounter()
def x1 = counter.incrementBy 10
def x2 = counter.incrementBy 20
def x3 = counter.update 'Hello'
x1.get() //block
x2.get() //block
x3.get() //block
assert 35 == counter.value

您可能需要提供有关执行流的确切信息的更多信息,以获得更好的信息。

您还可以将注释更改为指示阻止:

@ActiveMethod(blocking=true)

有关上述任何内容的信息,请参阅相关文档。

第一个示例具有竞争条件,因为getValue()直接触及对象的未受保护的内部状态,而incrementBy()和update()都使用活动对象的内部actor来修改对象的状态。

在第二个示例中,由于非阻塞方法返回 Promise 的 instac,因此不允许提供特定的返回类型,例如 int。

根据 Brian 的建议,只需用 @ActiveMethod(blocking=true) 注释 getValue() 方法,这将允许您给出特定的返回类型。

@ActiveMethod(blocking=true)
int getValue() {...}

相关内容

最新更新