Java单例模式

单例模式有两种:懒汉式和饿汉式;
1、饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全。
2、从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题,写法简单明了,能用则用。但是它是加载类时创建实例。所以如果是一个工厂模式,缓存了很多实例,那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。
3、两者建立单例对象的时间不同。“懒汉式”是在你真正用到的时候才去建这个单例对象,“饿汉式”是在不管用不用得上,一开始就建立这个单例对象。


image.png

其中饿汉式因为对象已经初始化了,所以线程不会误操作
饿汉式因为对象已经初始化了,所以线程不会误操作,但是懒汉式如何多个线程同时调用构造,如何实现线程安全呢?

#include 
 #include 
 using namespace std;

 class Singleton
 {
 private:
 Singleton()
 {
 sleep(5);
 printf (" 构造函数被调用 \n");
 }

 public:
 static Singleton* GetInstance()
 {
 // printf (" 获取对象 \n");
 if (m_instance == NULL)
 {
 pthread_mutex_lock(&m_lock); //  上锁
 if (m_instance == NULL)
 m_instance = new Singleton;

 pthread_mutex_unlock(&m_lock); //  解锁
 }

 return m_instance;
 }

 private:
 static pthread_mutex_t m_lock; //  互斥锁
 static Singleton *m_instance;
 };
 Singleton *Singleton::m_instance = NULL;
 pthread_mutex_t Singleton::m_lock = PTHREAD_MUTEX_INITIALIZER;



 void *worker(void* arg)
 {
 Singleton* p = Singleton::GetInstance();
 }

 int main()
 {
 for (int i = 0; i < 10; i++)
 {
 pthread_t id;
 pthread_create(&id, NULL, worker, NULL);
 pthread_detach(id); //  线程分离
 }

 pthread_exit(NULL);
 return 0;
 }

你可能感兴趣的:(Java单例模式)