先日、投稿したPython で書くシングルトンに続いて、 synchronized メソッド
threading の Lock を使って書く。
シングルトンのメソッドを synchronized にするモデルが適していると思う。
utility.py
import threading def singleton(cls): instances = {} def getinstance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return getinstance def synchronized(func): func.__lock__ = threading.Lock() def synced_function(*args, **kwargs): with func.__lock__: return func(*args, **kwargs) return synced_function
サンプル
from utility import singleton from utility import synchronized import time @singleton class MyClass(): def __init__(self): self.id = 0 @synchronized def nextId(self): self.id = self.id + 1 # サンプルなので遅く。。。 time.sleep(1) return self.id
import threading def execute(): a = MyClass() for v in range(1, 6): id = a.nextId() print("%s : id = %d" % (threading.currentThread().name, id)) if __name__ == '__main__': thread1 = threading.Thread(target=execute) thread2 = threading.Thread(target=execute) thread1.start() thread2.start() thread1.join() thread2.join()
結果
Thread-1 : id = 1 Thread-2 : id = 2 Thread-1 : id = 3 Thread-2 : id = 4 Thread-1 : id = 5 Thread-2 : id = 6 Thread-1 : id = 7 Thread-2 : id = 8 Thread-2 : id = 9 Thread-1 : id = 10