Groovy - GPars - Активный объект - Активный метод, который возвращает значение
В Groovy мне нужно реализовать экземпляр ActiveObject с именем MyCounter
чтобы следующий код прошел:
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 и, таким образом, переменная counter фактически доступна до завершения операций incrementBy.
2.
@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
2 ответа
Хорошо, исходя из предположения, что это 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() используют внутренний субъект активного объекта для изменения состояния объекта.
Во втором примере, поскольку неблокирующие методы возвращают исходные данные Promise, вам не разрешено указывать конкретный тип возвращаемого значения, например int.
В соответствии с тем, что предлагает Брайан, просто аннотируйте метод getValue() @ActiveMethod(blocking=true)
, который позволит вам указать конкретный тип возврата.
@ActiveMethod(blocking=true)
int getValue() {...}