Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - Double checked locking - Пример использования в C#02 мая 2011Оглавление: 1. Double checked locking 2. Пример использования в Java 3. Пример использования в C# public sealed class Singleton { private Singleton { // инициализировать новый экземпляр объекта } private static volatile Singleton singletonInstance; private static readonly Object syncRoot = new Object; public static Singleton GetInstance { // создан ли объект if { // нет, не создан // только один поток может создать его lock { // проверяем, не создал ли объект другой поток if { // нет не создал — создаём singletonInstance = new Singleton; } } } return singletonInstance; } } Microsoft подтверждает, что при использовании ключевого слова volatile, использование паттерна Double checked locking является безопасным. Пример использования в PythonСледующий код на языке Python показывает пример реализации отложенной инициализации в сочетании с шаблоном Double checked locking: # require Python2 or Python3 #-*- coding: UTF-8 *-* import threading class SimpleLazyProxy: '''ленивая инициализация объекта безопасная для многонитевого использования''' def __init__: self.__lock = threading.RLock self.__obj = None self.__factory = factory def __call__: '''функция для доступа к настоящему объекту если объект не создан, то он создаcтся''' # пробуем получить "быстрый" доступ к объекту: obj = self.__obj if obj is not None: # получилось! return obj else: # объект возможно ещё не создан with self.__lock: # получаем доступ к объекту в эксклюзивном режиме: obj = self.__obj if obj is not None: # оказалось объект уже создан. # не будем повторно его создавать return obj else: # объект действительно ещё не создан. # создадим же его! obj = self.__factory self.__obj = obj return obj __getattr__ = lambda self, name: \ getattr, name) def lazy: '''декоратор превращающий класс, в класс с ленивой инициализацией средствами Proxy-класса''' class ClassDecorator: def __init__: # инициализация декоратора, # но не декорируемого класса и не Proxy-класса self.cls = cls def __call__: # запрос инициализации Proxy-класса # передадим Proxy-классу нужные параметры # для инициализации декорируемого класса return proxy_cls) return ClassDecorator # простая проверка: def test_0: print import time @lazy # экземпляры этого класса будут с ленивой инициализацией class TestType: def __init__: print # искусственно увеличим время создания объекта, # для нагнетения конкуренции нитей time.sleep self.name = name print def test: print # один такой экземпляр будет взаимодействовать с несколькими нитями test_obj = TestType target_event = threading.Event def threads_target: # функция которую будут выполнять нити: # ждём наступления специального события target_event.wait # как только это событие наступит -- # все 10 нитей одновременно обратятся к тестовому объекту # и в этот момент он инициализируется, в одной из нитей test_obj.test # создадим этих 10 нитей, с вышеописанным алгоритмом threads_target threads = for thread in range: thread = threading.Thread thread.start threads.append print # подождём немного времени... time.sleep # ...и запустим test_obj.test одновременно во всех нитях print target_event.set # завершение for thread in threads: thread.join print Просмотров: 2754
|