I have wrote two classes. The first class MySingletonTSafe is thread-safe because I use threading.Lock() to control how to call the method that creates the instance. But I'm not sure whether the second class MySingletonNTSafe is thread-safe. How could the sencond class be proved not thread-safe if it is?
I have found the thread Creating a singleton in python but it couldn't solve my puzzle.
The following is my code:
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
import threading
import Queue
import time
import random
class MySingletonTSafe(object):
    """implement Singleton pattern, thread-safe"""
    _instance = None
    _lock = threading.Lock()
    def __new__(cls):
        if MySingletonTSafe._instance is None:
            with MySingletonTSafe._lock:
                if MySingletonTSafe._instance is None:
                    MySingletonTSafe._instance = super(MySingletonTSafe, cls).__new__(cls)
        return MySingletonTSafe._instance
    def __init__(self):
        MySingletonTSafe._instance = self
class MySingletonNTSafe(object):
    """implement Singleton pattern, not-thread-safe"""
    _instance = None
    def __new__(cls):
        if MySingletonNTSafe._instance is None:
            # time.sleep(random.randint(1, 10))
            MySingletonNTSafe._instance = super(MySingletonNTSafe, cls).__new__(cls)
        return MySingletonNTSafe._instance
    def __init__(self):
        MySingletonNTSafe._instance = self
class Test(object):
    """Test whether the class MySingleton works"""
    def __init__(self, tnum=3):
        self.tnum = tnum
        self.queue_st = Queue.Queue()
        self.queue_nst = Queue.Queue()
    def run(self):
        threads_s = [threading.Thread(target=self._run_st) for i in xrange(self.tnum)]
        for t in threads_s:
            t.start()
            t.join()
        threads_ns = [threading.Thread(target=self._run_nst) for i in xrange(self.tnum)]
        for t in threads_ns:
            t.start()
            t.join()
    def _run_st(self):
        # thread-safe case
        obj = MySingletonTSafe()
        self.queue_st.put(obj)
    def _run_nst(self):
        # not-thread-safe case
        obj = MySingletonNTSafe()
        self.queue_nst.put(obj)
if __name__ == '__main__':
    test = Test(tnum=10)
    test.run()
    objs_st = []
    while not test.queue_st.empty():
        objs_st.append(test.queue_st.get())
    last = objs_st.pop()
    for obj in objs_st:
        if not last == obj:
            print('NOT IDENTICAL')
            break
        else:
            print('IDENTICAL')
    objs_nst = []
    while not test.queue_nst.empty():
        objs_nst.append(test.queue_nst.get())
    last = objs_nst.pop()
    for obj in objs_nst:
        if not last == obj:
            print('NOT IDENTICAL')
            break
        else:
            print('IDENTICAL')
 
     
    