Синхронизация с объектом, который будет создан

Есть ли какие-либо проблемы синхронизации / ссылки с этим кодом?

(Предположим, что myStrings уже создан.)

MySynch.java:

public class MySynch
{
    public static String[] myStrings = new String[10];

    public static void updateStrings()
    {
        synchronized (myStrings)
        {
            myStrings = new String[10]; // Safe?

            myStrings[0] = something[0];
            myStrings[1] = somethingElse[4];
        }
    }
}

Массив объектов myStrings может быть прочитано более чем одним потоком и имеет один поток, который обновляет (записывает) его, выполняя updateStrings(), Потоки, которые читают с него, также будут использовать synchronized (myStrings) Блок для чтения из него, конечно же, для безопасности.

Существуют ли проблемы с блокировкой массива и повторной его реализацией внутри synchronized блок, который его блокирует (как указано выше)?

4 ответа

Решение

Существует проблема синхронизации: когда myStrings установлен в новый экземпляр, а второй поток выполняет метод сразу после этого, этот второй поток синхронизирует второй экземпляр myStrings.

Вы должны синхронизироваться по классу или любому другому статическому конечному объекту с

synchronized(MySynch.class) {
    ...
}

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

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

// update
synchronized (YourClass.class) {
    // update
}

// get
synchronized (YourClass.class) {
    // get
}

Очиститель, ИМО.

public class MySynch {
private static AtomicReference<String[]> myStrings = new AtomicReference<String[]>(
        new String[0]);

public static void updateStrings() {
    String[] tmp = new String[2];
            ....
    myStrings.set(tmp);

}

public static String[] getStrings() {
    return myStrings.get();
}

}
Другие вопросы по тегам