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() {...}
Другие вопросы по тегам