Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - Double checked locking - Пример использования в Java02 мая 2011Оглавление: 1. Double checked locking 2. Пример использования в Java 3. Пример использования в C# Рассмотрим следующий код на языке Java, взятый из: // Однопоточная версия class Foo { private Helper helper = null; public Helper getHelper { if helper = new Helper; return helper; } // и остальные члены класса… } Этот код не будет корректно работать в многопоточной программе. Метод // Правильная, но "дорогая" по времени выполнения многопоточная версия class Foo { private Helper helper = null; public synchronized Helper getHelper { if helper = new Helper; return helper; } // и остальные члены класса… } Этот код работает, но он вносит дополнительные накладные расходы на синхронизацию. Первый вызов
// Неработающая многопоточная версия // Шаблон "Double-Checked Locking" class Foo { private Helper helper = null; public Helper getHelper { if { synchronized { if { helper = new Helper; } } } return helper; } // и остальные члены класса… } На интуитивном уровне, этот код кажется корректным. Однако, существуют некоторые проблемы, которых следует избежать. Представим себе, что события в многопоточной программе протекают так:
Одна из опасностей использования блокировки с двойной проверкой в J2SE 1.4 состоит в том, что часто кажется, что программа работает корректно. Во-первых, рассмотренная ситуация будет возникать не очень часто; во-вторых, сложно отличить корректную реализацию данного шаблона от такой, которая имеет описанную проблему. В зависимости от компилятора, распределения планировщиком процессорного времени для потоков, а также природы других работающих конкурентных процессов, ошибки, спровоцированные с некорректной реализацией блокировки с двойной проверкой, обычно происходят бессистемно. Воспроизведение таких ошибок обычно затруднено. Можно решить проблему при использовании J2SE 5.0. Новая семантика ключевого слова // Работает с новой семантикой volatile // Не работает в Java 1.4 и более ранних версиях из-за семантики volatile class Foo { private volatile Helper helper = null; public Helper getHelper { if { synchronized { if helper = new Helper; } } return helper; } // и остальные члены класса… } Было предложено много вариантов блокировки с двойной проверкой, которые явно не сообщают то, что объект полностью сконструирован, и все они являются некорректными. Просмотров: 2755
|