Нужно ли летучее здесь? - PullRequest
1 голос
/ 19 января 2012

В следующем гипотетическом сценарии и из-за желания лучше понять язык, переменная требуется для int [] ссылки?

public final class SO {

    private int[] ar = new int[10];  // is volatile needed here?
    private int idx = 0;

    public synchronized int get( int i ) {
        return ar[i];
    }

    public synchronized void append( final int val ) {
        if ( idx == ar.length ) {
            // array is too small, let's grow it
            final int[] prev = ar;
            ar = new int[ar.length+ar.length*20/100]
            System.arrayCopy(prev, 0, ar, 0, prev.length);
        }
        ar[idx++] = val;
    }

}

Единственный способ получить int через синхронизированный метод , и единственный способ изменить int [] (включая создание нового int [] ) такжесделано через синхронизированный метод.

Мне не нужно добавлять какие-либо дополнительные права синхронизации?

Ответы [ 4 ]

3 голосов
/ 19 января 2012

Нет, volatile не требуется, поскольку к нему обращаются только внутри синхронизированных методов, поэтому он уже поточно-ориентирован. Никакой дополнительной безопасности потока не требуется в вашем коде.

2 голосов
/ 19 января 2012

это будет так же, как вы сказали, так как int защищен блокировкой класса - но это будет очень медленно, так как доступ для записи и чтения блокирует друг друга.(см. реализацию CopyOnWriteList для более быстрого способа)

1 голос
/ 19 января 2012

Согласно спецификации Java Java изменчивое добавление строгих правил для потоков (чтение / запись из основной памяти), использование синхронизированных релаксов в этом небольшом фрагменте.

1 голос
/ 19 января 2012

С вами все в порядке, если только к вашим значениям нет доступа в другом месте без синхронизации.

Кстати, если бы вы сделали ar volatile вместо использования синхронизированных методов, вам нужно было бы сделать idx Летучие тоже.Но это все равно не будет достаточной синхронизацией, потому что два разных потока, выполняющих append одновременно, могут нанести ущерб.

На самом деле, есть другая проблема с использованием массива volatile: изменение значения в массиве делаетне запускать синхронизацию кеша.Только переназначение массива (как вы делаете при создании большего массива) вызывает сброс кеша.

...