在python中实现单例模式(面试经典题)

什么是单例模式:

单例模式是一种常用的软件设计模式,该模式的目的就是确保某个类只有一个类的存在,单例模式涉及到一个单一的类,这个类提供了唯一的对象的方式,可以直接被访问,不需要实例化类的对象

在非多线程的环境中实现

class Singleton:
    # 设置一个类变量,先让变量为空
    instance = None

    # 定义init方法初始化
    def __init__(self, name):
        self.name = name

    # 定义new方法
    def __new__(cls, *args, **kwargs):
        # 返回空对象
        if cls.instance:
            return cls.instance
        cls.instance = object.__new__(cls)
        return cls.instance


obj1 = Singleton("aaa")
obj2 = Singleton("xxx")
print(obj1, obj2)

这样就完成了我们普通模式下的单例模式

然而在我们的多线程下

先用多线程的方法书写一下我们的单例模式

# 导入多线程模块
import threading


class Singleton:
    instance = None

    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        if cls.instance:
            return cls.instance
        cls.instance = object.__new__(cls)
        return cls.instance


# 定义单例函数
def task():
    obj = Singleton('xxx')
    print(obj)


# 多线程执行task函数
for i in range(10):
    t = threading.Thread(target=task)
    t.start()

这时我们看一下结果

在python中实现单例模式(面试经典题)_第1张图片

 这是我们发现单例模式成功,那为什么会出现这样

是因为这样存在偶然性,因为我们的线程过短,我们导入time模块来试验一下

# 导入多线程模块
import threading
# 导入time模块
import time


class Singleton:
    instance = None

    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        if cls.instance:
            return cls.instance
        time.sleep(0.1)
        cls.instance = object.__new__(cls)
        return cls.instance


# 定义单例函数
def task():
    obj = Singleton('xxx')
    print(obj)


# 多线程执行task函数
for i in range(10):
    t = threading.Thread(target=task)
    t.start()

运行一下发现

在python中实现单例模式(面试经典题)_第2张图片

 此时发现单例模式失败

这时我们就可以通过锁的方式来完善单例模式

# 导入多线程模块
import threading
# 导入time模块
import time


class Singleton:
    # 定义RLock锁
    lock = threading.RLock()
    instance = None

    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        with cls.lock:
            if cls.instance:
                return cls.instance
            time.sleep(0.1)
            cls.instance = object.__new__(cls)
            return cls.instance


# 定义单例函数
def task():
    obj = Singleton('xxx')
    print(obj)


# 多线程执行task函数
for i in range(10):
    t = threading.Thread(target=task)
    t.start()

我们运行验证一下

在python中实现单例模式(面试经典题)_第3张图片

发现我们实例模式成功

最后我们最终完善一下我们的代码 

# 导入多线程模块
import threading


class Singleton:
    # 定义RLock锁
    lock = threading.RLock()
    instance = None

    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        if cls.instance:
            return cls.instance
        with cls.lock:
            if cls.instance:
                return cls.instance
            cls.instance = object.__new__(cls)
            return cls.instance


# 定义单例函数
def task():
    obj = Singleton('xxx')
    print(obj)


# 多线程执行task函数
for i in range(10):
    t = threading.Thread(target=task)
    t.start()

然后我们的实例模式就完成了

你可能感兴趣的:(python,python并发编程,多线程,python,面试)