單例模式有兩種:懶漢式和餓漢式;
1贼陶、餓漢式是線程安全的,在類創(chuàng)建的同時就已經創(chuàng)建好一個靜態(tài)的對象供系統(tǒng)使用,以后不在改變蹂窖。懶漢式如果在創(chuàng)建實例對象時不加上synchronized則會導致對對象的訪問不是線程安全欣福。
2绢片、從實現方式來講他們最大的區(qū)別就是懶漢式是延時加載,他是在需要的時候才創(chuàng)建對象,而餓漢式在虛擬機啟動的時候就會創(chuàng)建,餓漢式無需關注多線程問題畏陕,寫法簡單明了配乓,能用則用。但是它是加載類時創(chuàng)建實例。所以如果是一個工廠模式犹芹,緩存了很多實例崎页,那么就得考慮效率問題,因為這個類一加載則把所有實例不管用不用一塊創(chuàng)建腰埂。
3飒焦、兩者建立單例對象的時間不同∮炝“懶漢式”是在你真正用到的時候才去建這個單例對象牺荠,“餓漢式”是在不管用不用得上,一開始就建立這個單例對象刁卜。
其中餓漢式因為對象已經初始化了志电,所以線程不會誤操作
餓漢式因為對象已經初始化了曙咽,所以線程不會誤操作蛔趴,但是懶漢式如何多個線程同時調用構造,如何實現線程安全呢例朱?
#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;
}