Es gibt viele viele Details, die ausführlich diskutiert werden könnten. Aber im Kern:
Diese erfordern immer eine Sperre irgendwo getroffen werden oder irgendwie:
@synchronized(...) { ... }
[lock lock];
Locks sind sehr teuer für die Gründe, die Sie erwähnen, Sie verbrauchen notwendigerweise Kernel-Ressourcen. (Der @synchronized() - Fall kann heutzutage tatsächlich Kernel-Sperren vermeiden, aber es ist ein Hash-basierter Ausschlussmechanismus, der an sich teuer ist).
Und diese brauchen nicht immer eine Sperre (aber manchmal vielleicht tun):
dispatch_sync(...concurrent q...., ^{ ... });
dispatch_async(...queue of any kind...., ^{ ... });
Es gibt einen schnellen Weg durch den Versandfunktionen, die effektiv sind Lockless (obwohl sie verwenden Test-and-Set Atom Primitive, die unter Last Performance-Probleme verursachen können).
Das Endergebnis ist, dass ein synchroner Versand an eine gleichzeitige Warteschlange effektiv behandelt werden kann wie "dies auf diesem Thread jetzt ausführen". Eine synchrone Verteilung an eine serielle Warteschlange kann das atomare Test-and-Set ausführen, um zu testen, ob die Warteschlange verarbeitet wird, es als besetzt markieren und, wenn es nicht besetzt ist, den Block für den aufrufenden Thread sofort ausführen.
Asynchrone Versendungen können ähnlich schnell sein, obwohl asynchroner Versand das Kopieren des Blocks erfordert (was sehr billig sein kann, aber etwas zum Nachdenken).
Im Allgemeinen kann GCD alles tun, was eine Sperre kann, kann es zumindest - wenn nicht mehr - effizient tun, und Sie können die GCD-APIs weit über das einfache Sperren hinaus verwenden (mit einem Semaphor als Berechnungsdrossel, zum Beispiel).
BTW: Wenn Ihre Aufgaben relativ grobkörnig sind, werfen Sie einen Blick auf NSOperationQueue
und NSOperation
.