Java单例模式
2019-09-30 本文已影响0人
爱宝宝n
单例模式有两种:懒汉式和饿汉式;
1、饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全。
2、从实现方式来讲他们最大的区别就是懒汉式是延时加载,他是在需要的时候才创建对象,而饿汉式在虚拟机启动的时候就会创建,饿汉式无需关注多线程问题,写法简单明了,能用则用。但是它是加载类时创建实例。所以如果是一个工厂模式,缓存了很多实例,那么就得考虑效率问题,因为这个类一加载则把所有实例不管用不用一块创建。
3、两者建立单例对象的时间不同。“懒汉式”是在你真正用到的时候才去建这个单例对象,“饿汉式”是在不管用不用得上,一开始就建立这个单例对象。
image.png
其中饿汉式因为对象已经初始化了,所以线程不会误操作
饿汉式因为对象已经初始化了,所以线程不会误操作,但是懒汉式如何多个线程同时调用构造,如何实现线程安全呢?
#include <iostream>
#include <pthread.h>
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;
}