Двойная проверка на null
Тот кто изучал исходники CLR, или писал многопоточный код много раз видел подобный код:
Сегодня, в одном весьма нетривиальном коде, мне пришлось еще одну вариацию написать:
if (a == null) lock (this) {Лично я, когда увидел его впервые, был удивлен двойной проверкой. Но, подумав, понял зачем это надо. Ведь пока мы ждали блокировки (это могло быть достаточно длинное ожидание, в случае, если объектом this владел кто-то другой), кто-то мог уже изменить переменную a.
if (a == null) a = new A();
}
Сегодня, в одном весьма нетривиальном коде, мне пришлось еще одну вариацию написать:
if (a == null)Суть почти та же, что и в предыдущем примере. Почти, потому что есть несколько отличий:
Interlocked.CompareExchange(ref a, new A(), null);
- Нет блокировки потоков (все помнят что функции Interlocked работают гораздо быстрее, чем использование Monitor-ов).
- Объект A может создается после первой проверки, но до второй. Это означает, что он может создаваться лишний раз и потому такой вариант не подходит, если это создание имеет побочный эффект.
Коментарі