Синхронизация с объектом, который будет создан
Есть ли какие-либо проблемы синхронизации / ссылки с этим кодом?
(Предположим, что 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();
}
}