今天在看多線程同步時,忽然想到了單例的同步問題。自從dispatch_once出現後,咱們建立單例很是簡單且安全:安全
1 static dispatch_once_t pred; 2 static SingleObject *sharedObject = nil; 3 4 dispatch_once(&pred, ^{ 5 sharedObject = [[[self class] alloc] init]; 6 }); 7 return sharedObject;
蘋果簡潔的接口已經慢慢讓咱們忘記了建立單例時的同步問題。多線程
普通的建立單例方法:ide
1 static SingleObject *obj = nil; 2 3 @synchronized (self) { 4 if (obj == nil) { 5 obj = [[SingleObject alloc] init]; 6 } 7 } 8 9 return obj;
這麼寫是沒問題的,可是在多個線程同時調用時效率不高,能夠用著名的double check方法來提升效率:性能
1 static SingleObject *obj = nil; 2 3 if (obj == nil) { 4 @synchronized (self) { 5 if (obj == nil) { 6 obj = [[SingleObject alloc] init]; 7 } 8 } 9 }
若是沒有第一個if (obj == nil),每一次調用這個方法,都會用鎖操做來實現線程同步,這是很是消耗性能的。spa
加上if (obj == nil)後,第二次調用這個方法,就不會在進入到鎖模塊的代碼中,只有obj = nil時,纔會進入一次鎖代碼,線程
這樣能很好的提升因爲鎖帶來的性能問題。code