Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
 Аватар для danek130995
33 / 33 / 3
Регистрация: 25.05.2014
Сообщений: 1,137

Почему используется именно такая конструкция кода?

27.03.2018, 00:31. Показов 760. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Встретил в исходном коде одного проекта следующее, привожу пример части класса:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public final class ApiFactory {
    private static MovieService sService;
 
    public static MovieService getMoviesService() {
        //I know that double checked locking is not a good pattern, but it's enough here
        MovieService service = sService;
        if (service == null) {
            synchronized (ApiFactory.class) {
                service = sService;
                if (service == null) {
                    service = sService = createService();
                }
            }
        }
        return service;
    }
 
}
Комментарии автора говорят: "Я знаю, что двойная проверка блокировки не очень хорошая модель, но этого достаточно здесь "

Что это значит, двойная проверка блокировки? И почему используется такой странный код?
MovieService service = sService;
if (service == null) { - почему нельзя было проверить if (sService== null)? Зачем объявлять service?

Потом:
service = sService;
if (service == null) {
service = sService = createService();
}
Зачем сначала в service кладется sService , а потом опять в service кладется sService? Нельзя было написать
if (sService == null) {
sService = createService();
}
? ведь service = sService; - уже сделано было выше.
В общем, у меня подозрение, что это сделано не зря, может быть это как то связано с многопоточностью, хотелось бы узнать, как.
Кстати говоря, в другом проекте этого же человека поле sService уже объявлено как volatile, а комментарий про double checked удален. Может ли это быть как то связано?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.03.2018, 00:31
Ответы с готовыми решениями:

Почему не работает конструкция?
Данная конструкция почему-то не работает, цикл бесконечно повторяется, даже при вводе слова, которое должно привести к завершению цикла. ...

Массивы. Почему работает такая конструкция?
Почему это работает и где можно об этом прочитать? По объявлению массив статический, фактически - динамический???? Где под такой массив...

Почему не работает ТАКАЯ конструкция функции time
вот фрагмент кода. int main(){ time_t testsec; //определил переменную типа ТАймТ time(&testsec); // Извлекаю в переменную...

11
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
27.03.2018, 06:23
когда гуглить то научишься?
https://en.wikipedia.org/wiki/... ed_locking
1
 Аватар для danek130995
33 / 33 / 3
Регистрация: 25.05.2014
Сообщений: 1,137
27.03.2018, 14:10  [ТС]
xoraxax,
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Работает с новой семантикой volatile
// Некорректно работающая (в Symantec JIT и устаревших версиях Oracle JRE) многопоточная версия
// Шаблон "Double-Checked Locking"
class Foo {
    private Helper helper = null;
    public Helper getHelper() {
        if (helper == null) {
            synchronized(this) {
                if (helper == null)
                    helper = new Helper();
            }
        }
        return helper;
    }
 
    // и остальные члены класса…
}
Написано, что
Семантика некоторых языков программирования такова, что потоку А разрешено присвоить разделяемой переменной ссылку на объект, который находится в процессе инициализации (что в общем-то вполне однозначно нарушает причинно-следственную связь, ведь программист вполне явно просил присваивать переменной ссылку на объект [то есть — опубликовать ссылку в общий доступ] — в момент после инициализации, а не в момент до инициализации).

Поток Б замечает, что переменная инициализирована (по крайней мере, ему так кажется), и возвращает значение переменной без получения блокировки. Если поток Б теперь будет использовать переменную до того момента, когда поток А закончит инициализацию, поведение программы будет некорректным.
Я правильно понял, что в какой-то может произойти так, что поток А присвоит helper ссылку на объект, который еще не инициализирован, и в это время поток Б подумает, что helper уже инициализирован, и вернет его?
Тогда как поможет volatile в этом случае?
Java
1
 private volatile Helper helper = null;
Volatile просто гарантирует, что значение переменной в двух потоках всегда будет читаться из общей памяти, а не из кэша и будет одинаково всегда для обоих потоков.
Как это может помочь тому, что присвоение ссылки на объект Helper будет гарантированно выполнено только после инициализации объекта? Получается, volatile не только отвечает за одинаковое значение в обоих потоках, но и за гарантированную инициализацию?

И все же остается непонятным зачем автор использует локальную переменную service, когда можно использовать поле класса sService
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
27.03.2018, 14:28
всю статью в википедии прочитал? там по шагам рассматривается несколько вариантов и проблемы, которые в них возникают
1
 Аватар для danek130995
33 / 33 / 3
Регистрация: 25.05.2014
Сообщений: 1,137
27.03.2018, 14:52  [ТС]
xoraxax, а, прошу прощения, я просто открыл русский вариант, а там оказывается опущено много было.
Получается, я правильно высказал предположение про volatile:
The volatile keyword now ensures that multiple threads handle the singleton instance correctly
На счет локальной переменной:
Note the local variable "localRef", which seems unnecessary. The effect of this is that in cases where helper is already initialized (i.e., most of the time), the volatile field is only accessed once (due to "return localRef;" instead of "return helper;"), which can improve the method's overall performance by as much as 25 percent.[7]
Получается это сделано для того, чтобы метод потом уже возвращал не-volatile переменную, что ускорит его работу на 25 %?

Остался вопрос, почему тогда в этом месте :
Java
1
2
3
4
5
6
synchronized(this) {
                localRef = helper;
                if (localRef == null) {
                    helper = localRef = new Helper();
                }
            }
Нельзя выполнить проверку if (helper == null) ? Почему выполняется localRef = helper; if (localRef == null) ?
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
27.03.2018, 15:03
написано же, чтоб к волатайл не обращаться
0
 Аватар для danek130995
33 / 33 / 3
Регистрация: 25.05.2014
Сообщений: 1,137
27.03.2018, 15:05  [ТС]
xoraxax, так мы все равно ж обращаемся к ней в этом месте:
localRef = helper;
Какая разница, что мы так обратимся к ней 1 раз, что сразу так: if (helper == null) , минуя localRef = helper;?
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
27.03.2018, 16:27
danek130995, Так мы обращаемся только один раз.
Если бы писали if (helper == null) в секции else пришлось бы ещё раз писать чтение volatile переменной helper
0
 Аватар для danek130995
33 / 33 / 3
Регистрация: 25.05.2014
Сообщений: 1,137
28.03.2018, 12:42  [ТС]
turbanoff, так у нас же нет секции else в данном отрывке кода

Добавлено через 19 часов 33 минуты
xoraxax, turbanoff, ?
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
30.03.2018, 15:19
danek130995, Напишите код, который вы хотите обсудить.
Как я понимаю, вы предлагаете такой вариант:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
    private static volatile MovieService sService;
 
    public static MovieService getMoviesService() {
        MovieService localRef = sService;
        if (localRef == null) {
            synchronized (ApiFactory.class) {
                if (sService == null) {
                    localRef = sService = createService();
                }
            }
        }
        return localRef;
    }
Если внимательно присмотреться, то можно увидеть, что в таком виде, метод может вернуть null, что некорректно.
1
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4575 / 2774 / 491
Регистрация: 28.04.2012
Сообщений: 8,779
30.03.2018, 15:33
danek130995, https://youtu.be/C6b_dFtujKo?t=20m32s
1
 Аватар для danek130995
33 / 33 / 3
Регистрация: 25.05.2014
Сообщений: 1,137
30.03.2018, 16:16  [ТС]
turbanoff, да, спасибо, Вы правы, не увидел сразу, сейчас увидел.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.03.2018, 16:16
Помогаю со студенческими работами здесь

Почему не проходит такая конструкция счетчика на странице HTML?
Господа, кто знает почему не проходит такая конструкция счетчика на странице HTML <script...

Почему выпадает именно такая ошибка?
Привет. Программа со списком и почему то выпадает ошибка: Module.pas(113): Constructing instance of 'TStrings' containing abstract...

Класс без имени: почему у меня скомпилировалась такая конструкция?
Приветствую! Почему у меня скомпилировалась такая конструкция? class { private: int n; public: };

Почему у тебя именно такая аватарка/фотография?
Напиши, почему ты поставил себе именно такую аватарку/фотографию. Я: Аватар доктора Джона Зойдберга из Футурамы. Почему? Потому что:...

Почему в MessageBox именно такая расстановка фраз
Подскажите,пожалуйста,почему надо писать так public void Said(string message,Sasha wooorld) { MessageBox.Show(wooorld.Name +...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru