Интернет магазин китайских планшетных компьютеров



Компьютеры - 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




Просмотров: 2662


<<< Фобос (КА)
Vendor lock-in >>>