Всем, кто переживает за частично построенный объект:
Насколько я понимаю, проблема частично построенных объектов - это только проблема внутри конструкторов. Другими словами, в конструкторе, если объект ссылается на себя (включая его подкласс) или его члены, то возможны проблемы с частичным построением. В противном случае, когда конструктор возвращается, класс полностью создан.
Я думаю, что вы путаете частичную конструкцию с другой проблемой того, как компилятор оптимизирует записи. Компилятор может выбрать A) выделить память для нового объекта Helper, B) записать адрес в myHelper (локальная переменная стека), а затем C) вызвать инициализацию любого конструктора. В любое время после точки B и до точки C доступ к myHelper будет проблемой.
Именно эта оптимизация компиляции записей, а не частичная конструкция, связана с цитируемыми статьями. В исходном решении блокировки с одной проверкой оптимизированные записи могут позволить нескольким потокам видеть переменную-член между точками B и C. Эта реализация позволяет избежать проблемы оптимизации записи с помощью локальной переменной стека.
Основная область цитируемых работ - описание различных проблем, связанных с решением с двойной проверкой блокировки. Однако, если метод atomicSet также не синхронизируется с классом Foo, это решение не является решением с двойной проверкой блокировки. Он использует несколько замков.
Я бы сказал, что все это сводится к реализации атомарной функции присваивания. Функция должна быть по-настоящему атомарной, она должна гарантировать синхронизацию кэшей локальной памяти процессора и делать все это с меньшими затратами, чем просто всегда синхронизировать метод getHelper.
Исходя из цитируемой статьи, на Java вряд ли будет соответствовать всем этим требованиям. Кроме того, кое-что, что должно быть очень ясно из бумаги, - то, что модель памяти Java часто изменяется. Он адаптируется к лучшему пониманию процессов кэширования, сбора мусора и т. Д., А также адаптируется к изменениям в базовой архитектуре реального процессора, на которой работает виртуальная машина.
Как правило, если вы оптимизируете свой Java-код способом, который зависит от базовой реализации, в отличие от API, вы рискуете получить неработающий код в следующей версии JVM. (Хотя иногда у тебя не будет выбора.)
dsimcha:
Если ваш метод atomicSet является реальным, то я постараюсь отправить ваш вопрос Дугу Ли (вместе с вашей реализацией atomicSet). У меня такое чувство, что он из тех парней, которые ответят. Я предполагаю, что для Java он скажет вам, что дешевле всегда синхронизироваться и искать оптимизацию в другом месте.