Java Atomity и хороший фреймворк для сравнения и обмена?

Как вы, ребята, думаете, это хорошая общая структура для атомарных операций? Кроме того, как вы думаете, правильно ли говорить, что в отношении приложений Java отдельные байтовые коды являются атомарными, поскольку нет возможности выполнять более одного байтового кода за раз с помощью одной JVM? Итак, если бы был однобайтовый код для if else, то эта инструкция if else была бы атомарной?

// CAS, Compare and Swap
public abstract class CASOperation<T> {

protected T valueAtStart;

public CASOperation(){
    valueAtStart = objectToReview();
}

public void exec(){
    synchronized(this){
        while(!valueAtStartEqualsTheCurrent()){
            valueAtStart = objectToReview();
        }
        execImp();
    }
}

private boolean valueAtStartEqualsTheCurrent() {
    if (objectToReview().equals(valueAtStart)){
        return true;
    } else {
        return false;
    }
}

abstract protected T objectToReview();

abstract protected void execImp();

На самом деле он предназначен для сравнения и выполнения, поэтому после проверки того, что исходное значение привязки не изменилось, мы выполняем некоторый блок кода.


person newlogic    schedule 08.02.2013    source источник


Ответы (2)


Я бы просто использовал java.util.concurrent.AtomicReference, если вы действительно нужна полная проверка на равенство вместо простого ==.

compareAndSet возвращает значение, указывающее, было ли значение ожидаемым, поэтому вы можете затем условно выполнить другой код.

Выполнение абстрактного метода в синхронизированном блоке звучит как потенциально рискованное дело — нет указаний или ограничений на то, сколько времени это может занять.

Скажем так: я думаю, что если бы я не знал о конкретных требованиях к использованию чего-то вроде предложенной вами структуры, я бы придерживался типов в java.util.concurrent.atomic.

person Jon Skeet    schedule 08.02.2013
comment
Да, я подумал, что было бы неплохо иметь общий способ сравнения любого объекта, отсюда и необходимость равных, я посмотрю, ура. - person newlogic; 08.02.2013
comment
@ user1037729: Вы всегда можете зациклиться, выполнив get, затем проверив равенство, затем выполнив compareAndSet, чтобы проверить, равно ли значение равно, используя существующую ссылку. - person Jon Skeet; 08.02.2013

Как вы, ребята, думаете, это хорошая общая структура для атомарных операций?

Да, это в файле java. пакет util.concurrent.atomic.

если бы для «если еще» был однобайтовый код, то эта инструкция «если еще» была бы атомарной?

Не обязательно — одна инструкция байт-кода может транслироваться более чем в одну машинную инструкцию.

Примечание: в вашем коде используется синхронизированный блок, который никогда не освобождается в рамках одного вызова, поэтому, если условие ложно при входе в блок, оно может никогда не стать истинным.

person assylias    schedule 08.02.2013
comment
Да, я понимаю, что один байт-код, вероятно, будет преобразован в более чем одну машинную инструкцию, но в отношении одного процесса Java я бы представил, что только один байт-код может выполняться за раз и, следовательно, будет атомарным, наверняка знаю другие приложения может вмешиваться в память в процессе Java? - person newlogic; 08.02.2013
comment
если !valueAtStartEqualsTheCurrent() оценивается как false, это будет означать, что начальное значение и текущее равны, и поэтому мы должны выполнить операцию. - person newlogic; 08.02.2013
comment
если !valueAtStartEqualsTheCurrent() имеет значение true, это будет означать, что начальное значение и текущее не равны, и поэтому мы не должны выполнять операцию. это то, что мы хотим, если оно никогда не станет ложным, это хорошо, поскольку мы хотим, чтобы операция была атомарной или что-то пропущено? - person newlogic; 08.02.2013
comment
@ user1037729 Вы смешиваете вещи. Один процесс Java может выполнять более одного байтового кода за раз, если имеется более одного процессора. Но даже на одном процессоре 2 потока могут чередоваться случайным образом, если не использовать синхронизацию. Например, такое простое выражение, как SomeType s = new SomeType();, не является атомарным. Таким образом, наблюдающий поток может увидеть, например, s в середине создания. - person assylias; 08.02.2013