设计模式(二)————单例模式(Singleton Pattern)

定义:确保某个类只有一个实例,并且自行实例化且向所有类提供这个实例。

单例模式有六种常用的创建方式:

1.懒汉式(线程不安全)

在单线程下,用懒汉式已经足够好了,但是一旦遇到多线程,就有可能出现多个实例。

2.懒汉式(线程安全)

在并发较低的情况下,该方案也可以使用,但是一旦并发较高,线程锁带来的时间消耗将变得不可接受,于是我们有了双重检查锁写法。

3.饿汉式

在一开始就获得一个实例,由于不知道什么时候会使用,所以这种方法会比较浪费资源。

4.双重检查/双重校验锁

双重检查锁在相当长的一段时间内迷惑了所有人,他的一些问题直到后来才被发现——即编译器对语句优化后,其真实的执行顺序可能和期望的执行顺序不同,用new申请一片内存,他有可能会先申请内存,然后返回给指针,最后再执行构造函数,这样的话,当它在执行构造函数之前,如果有新的线程来尝试获取这个实例,由于静态实例的指针已不为空,就会直接返回给这个线程这片为初始化内存的地址。当然后来事情解决了,Java等语言添加了volatile关键字,C++也可以使用atomic头文件来保证实际执行顺序和期望顺序一致。

5.登记式/静态内部类

6.枚举

UML类图:

 

C++实现:

//1.懒汉式(线程不安全)

class  SingleObject1
{
private:
	SingleObject1() {}
	static SingleObject1* Instance;
	~SingleObject1() { delete Instance; }
public:
	static SingleObject1* getInstance()
	{
		if (Instance == nullptr)
			Instance = new SingleObject1();
		return Instance;
	}
};

//2.懒汉式(线程安全)

class SingleObject2
{
private:
	SingleObject2() {}
	static SingleObject2* Instance;
	~SingleObject2() { delete Instance; }
	static mutex mt;
public:
	static SingleObject2* getInstance()
	{
		mt.lock();
		if (Instance == nullptr)
			Instance = new SingleObject2();
		mt.unlock();
		return Instance;
	}
};

//3.饿汉式

class SingleObject3
{
private:
	SingleObject3(){}
	static SingleObject3* Instance;
	~SingleObject3() { delete Instance; }
public:
	static SingleObject3* getInstance()
	{
		return Instance;
	}
};
SingleObject3* SingleObject3::Instance = new SingleObject3();

//4.双重检查/双重检验锁

class SingleObject4
{
private:
	SingleObject4() {}
	static atomic<SingleObject4*> Instance;
	~SingleObject4() { delete Instance; }
	static mutex mt;
public:
	static SingleObject4* getInstance()
	{
		SingleObject4* tmp = Instance.load(std::memory_order_relaxed);
		atomic_thread_fence(std::memory_order_acquire);

		if (tmp == nullptr)
		{
			lock_guard<mutex>lock(mt);
			tmp = Instance.load(memory_order_relaxed);
			if (tmp == nullptr)
			{
				tmp = new SingleObject4();
				atomic_thread_fence(std::memory_order_release);
				Instance.store(tmp, std::memory_order_relaxed);
			}
			mt.unlock();
		}
		return tmp;
	}
};

//5.登记式/静态内部类

class SingleObject5
{
private:
	SingleObject5() {}
	static class SingleObjectHolder
	{
		static SingleObject5* Instance;
		public:
			static SingleObject5* getInstanceOrg()
			{
				return Instance;
			}
	};
public:
	static SingleObject5* getInstance()
	{
		return SingleObjectHolder::getInstanceOrg();
	}
};
SingleObject5* SingleObject5::SingleObjectHolder::Instance= new SingleObject5();

//6.枚举
C++实现不了,见下面的C#中用Java代码代替的部分,如果有大佬能够用C++实现的希望能告知一下

 C#实现:

//1.懒汉式(线程不安全)

public class SingleObject1
    {
        private static SingleObject1 Instance;
        private SingleObject1() { }
        public static SingleObject1 getInstance()
        {
            if (Instance == null)
                Instance = new SingleObject1();
            return Instance;
        }
    }
//2.懒汉式(线程安全)

    public class SingleObject2
    {
        private static SingleObject2 Instance=null;
        private static readonly object padlock = new object(); 
        private SingleObject2() { }

        public static SingleObject2 getInstance()
        {
            lock (padlock)
            {
                if (Instance == null)
                   Instance = new SingleObject2();
            }
            return Instance;
       }
   }

//3.饿汉式  
  
public class SingleObject3
    {
        private static SingleObject3 instance = new SingleObject3();
        public int count = 0;
        private SingleObject3() { }
        public static  SingleObject3 getInstance()
        {
            return instance;
        }
        public void showMessage()
        {
            WriteLine("make yourself");
        }
    }

//4.双重检查/双重校验锁

    public class SingleObject4
    {
        private static SingleObject4 Instance = null;
        private static readonly object padlock = new object();
        private SingleObject4() { }

        public static SingleObject4 getInstance()
        {
            if(Instance==null)
            lock (padlock)
            {
                if (Instance == null)
                    Instance = new SingleObject4();
            }
            return Instance;
        }
    }

//5.登记式/静态内部类

    public class SingleObject5
    {
        private static class SingleObjectHolder
        {
           private static readonly SingleObject5 Instance =new SingleObject5();
           public static SingleObject5 INSTANCE
           {
                get { return Instance; }
           }
        }
        private SingleObject5() { }
        public static SingleObject5 getInstance()
        {
            return SingleObjectHolder.INSTANCE;
        }
    }

//6.枚举(C#的枚举特性不支持以下写法,所以用Java代替)

    public enum SingleObject6
    {
        INSTANCE,
        public void whateverMethod() { };
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值