Seit Kendall gebucht ein thread-sicheres Singleton, das versucht, Sperrkosten zu vermeiden, dachte ich, ich würde auch eine werfen:
#import <libkern/OSAtomic.h>
static void * volatile sharedInstance = nil;
+ (className *) sharedInstance {
while (!sharedInstance) {
className *temp = [[self alloc] init];
if(!OSAtomicCompareAndSwapPtrBarrier(0x0, temp, &sharedInstance)) {
[temp release];
}
}
return sharedInstance;
}
Okay, ich erkläre Ihnen, wie das funktioniert:
-
Schneller Fall: Bei normaler Ausführung sharedInstance
wurde bereits festgelegt, so dass die while
Schleife wird nie ausgeführt und die Funktion kehrt zurück, nachdem sie lediglich das Vorhandensein der Variablen geprüft hat;
-
Langsamer Fall: Wenn sharedInstance
nicht existiert, wird eine Instanz zugewiesen und mit Hilfe von Compare And Swap ('CAS') dorthin kopiert;
-
Angefochtener Fall: Wenn zwei Threads beide versuchen, die sharedInstance
zur gleichen Zeit UND sharedInstance
nicht zur gleichen Zeit existiert, werden beide neue Instanzen des Singletons initialisieren und versuchen, es in Position zu bringen. Wer das CAS gewinnt, kehrt sofort zurück, wer verliert, gibt die soeben zugewiesene Instanz wieder frei und gibt die (jetzt eingestellte) sharedInstance
. Der einzelne OSAtomicCompareAndSwapPtrBarrier
fungiert sowohl als Schreibsperre für den Einstell-Thread als auch als Lesesperre für den Test-Thread.