Название для этого шаблона?(Ответ: ленивая инициализация с двойной проверкой блокировки) - PullRequest
1 голос
/ 16 мая 2011

Рассмотрим следующий код:

public class Foo
{
    private static object _lock = new object();

    public void NameDoesNotMatter()
    {
        if( SomeDataDoesNotExist() )
        {
            lock(_lock)
            {
                if( SomeDataDoesNotExist() )
                {
                    CreateSomeData();
                }
                else
                {
                    // someone else also noticed the lack of data.  We
                    // both contended for the lock.  The other guy won
                    // and created the data, so we no longer need to.
                    // But once he got out of the lock, we got in.
                    // There's nothing left to do.
                }
            }
        }
    }

    private bool SomeDataDoesNotExist()
    {
        // Note - this method must be thread-safe.
        throw new NotImplementedException();
    }

    private bool CreateSomeData()
    {
        // Note - This shouldn't need to be thread-safe
        throw new NotImplementedException();
    }
}

Во-первых, есть некоторые предположения, которые мне нужно заявить:

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

  2. Foo может создаваться и использоваться одновременно из двух или более потоков. Я хочу, чтобы один из них в конечном итоге создал некоторые данные (но не оба), тогда я позволю обоим получить доступ к этим же данным (игнорировать потокобезопасность доступа к данным)

  3. Стоимость SomeDataDoesNotExist () невелика.

Теперь, это не обязательно должно быть ограничено некоторой ситуацией создания данных, но это был пример, о котором я мог подумать.

Частью, которую я особенно заинтересован в идентификации как образца, является проверка -> блокировка -> проверка. Мне приходилось несколько раз объяснять этот паттерн разработчикам, которые на первый взгляд не поняли алгоритм, но смогли оценить его.

Во всяком случае, другие люди должны делать то же самое. Это стандартизированная модель? Как это называется?

Ответы [ 4 ]

13 голосов
/ 16 мая 2011

Хотя я могу видеть, как вы думаете, это выглядит как блокировка с двойной проверкой, на самом деле это выглядит как опасно сломанная и неправильная блокировка с двойной проверкой .Без фактической реализации SomeDataDoesNotExist и CreateSomeData для критики у нас нет никакой гарантии, что эта штука на самом деле является поточно-ориентированной на каждом процессоре.

В качестве примера анализа того, как блокировка с двойной проверкой может пойти не так, посмотрите эту сломанную и неправильную версию блокировки с двойной проверкой:

C # ручная блокировка / разблокировка

Мой совет: не используйте технику с низким уровнем блокировки без веской причины и обзора кода от эксперта по модели памяти;вы, вероятно, ошибетесь.Большинство людей делают.

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

9 голосов
/ 16 мая 2011

Ленивая инициализация с двойной проверкой блокировки?

4 голосов
/ 16 мая 2011

Частью, которую я особенно заинтересован в идентификации как образца, является проверка -> блокировка -> проверка.

Это называется двойная проверка блокировки .

Помните, что в более старых версиях Java (до Java 5) это небезопасно из-за того, как была определена модель памяти Java.В Java 5 и более новые изменения были внесены в спецификацию модели памяти Java, так что теперь она безопасна.

0 голосов
/ 16 мая 2011

Единственное имя, которое приходит на ум для такого рода, - "Ошибка".Это имя используется в платформе iOS Core-Data с аналогичным эффектом.

По сути, ваш метод NameDoesNotMatter является отказом , и всякий раз, когда кто-то его вызывает, он приводит к заполнению объекта илиInitialized.

См. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html для более подробной информации о том, как используется этот шаблон проектирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...