Страницы

Поиск по вопросам

понедельник, 23 декабря 2019 г.

Зачем в getInstance synchronized?

#android #synchronized


Зачем в этом getInstance synchronized делать ?

Это класс-синглтон для работы с сетью с использованием retrofit.

public static NetworkWorker getInstance(){
    if (networkWorker == null){
        synchronized (NetworkWorker.class) {
            if (networkWorker == null) {
                networkWorker = new NetworkWorker();
            }
        }
    }
    return networkWorker;
}

    


Ответы

Ответ 1



При реализации синглтона даже с synchronized бывают случаи, когда при использовании многопоточности потокам удается дважды создать инстанс одного класса - что для реализации паттерна неприемлемо. Synchronized нужен, для того, что-бы в методе\объекте в данный момент мог работать лишь один поток, и остальные ожидали окончания работы. По сути это очередь. Если-бы это был просто класс, который необходимо защитить экраном synchronized - то проверка на null была бы одна, но поскольку здесь происходит реализация синглтона - то и проверки нужно сделать две.

Ответ 2



Паттерн называется Double checked locking. Призван в случае ленивой инициализации ликвидировать дорогую синхронизацию (в случае когда getInstance объявляется синхронным), которая нужна только когда несколько потоков обращаются за инстансом в момент его инициализации, при последующих обращениях синхронизация не нужна. У правильной реализации данного паттерна полно проблем: и happens before (когда ссылка на объект доступна вне критической секции до окончания инициализации) и деградация производительности из-за volatile... Если ситуация позволяет, то синглтон правильнее создавать сразу при объявлении. Либо гарантировать запуск потоков строго после инициализации синглтона, при этом DCL использовать ни к чему.

Комментариев нет:

Отправить комментарий