Интернет магазин китайских планшетных компьютеров |
|
Компьютеры - 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
Просмотров: 3134
|