在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() {...}