⚔️ 1. Was ist eine Data Race Condition?
Eine Data Race Condition entsteht, wenn zwei oder mehr Goroutines gleichzeitig auf dieselbe Speicheradresse zugreifen und mindestens ein Zugriff schreibend ist. Dies fĂĽhrt zu Speicher-Korruption oder Panics (z.B. concurrent map writes).
â–˛
[Goroutine 2: Schreiben] ──────(Muss warten!)
package main
import "sync"
type SafeCounter struct {
mu sync.Mutex
value int
}
func (c *SafeCounter) Inc() {
c.mu.Lock() // Kritischen Abschnitt sperren
defer c.mu.Unlock() // Sicherstellen, dass das Lock immer freigegeben wird
c.value++
}
⚡ 2. High-Performance: sync.RWMutex & sync/atomic
Wenn 99% aller Zugriffe nur lesend sind (z.B. in einem Cache), blockieren sich parallele Leser mit sync.Mutex unnötig. sync.RWMutex erlaubt beliebig viele parallele Leser (RLock), sperrt jedoch exklusiv für Schreiber (Lock).
// 1. sync.RWMutex fĂĽr leselastige Caches:
type Cache struct {
mu sync.RWMutex
data map[string]string
}
func (c *Cache) Get(key string) (string, bool) {
c.mu.RLock() // Mehrere Goroutines können gleichzeitig lesen!
defer c.mu.RUnlock()
val, ok := c.data[key]
return val, ok
}
// 2. Lock-freie Zähler mit Hardware-Atomics (sync/atomic):
import "sync/atomic"
var requestCount int64
func TrackRequest() {
atomic.AddInt64(&requestCount, 1) // Atomarer CPU-Befehl (kein Mutex-Overhead!)
}
func GetTotalRequests() int64 {
return atomic.LoadInt64(&requestCount)
}
Stell dir ein Buch im Lesesaal vor:
Mit RWMutex können 50 Studenten gleichzeitig das gleiche Buch lesen (RLock). Niemand stört den anderen. Kommt jedoch der Bibliothekar, um eine korrigierte Seite einzukleben (Lock), müssen alle Leser kurz absetzen, bis die Änderung fertig ist.
sync/atomic entspricht einem digitalen Drehkreuz am Eingang: Der Klickmechanismus schaltet blitzschnell mechanisch weiter, ohne dass ein Wachmann den Eingang absperren muss.
đź“‘ 3. Cheat-Sheet: Concurrency-Primitive im Vergleich
| Mechanismus | Bester Anwendungsfall | Lese-Performance | Schreib-Performance |
|---|---|---|---|
sync.Mutex |
Ausgewogene Lese-/Schreib-Muster, komplexe Zustände | Mittel (sequentiell) | Mittel |
sync.RWMutex |
Read-Heavy Workloads (>90% Leser, z.B. In-Memory Cache) | Sehr hoch (parallel) | Mittel |
sync/atomic |
Einfache Zähler, Flags, ID-Generierung, Metriken | Maximal (Lock-Free) | Maximal (Lock-Free) |
Channels |
Ăśbergabe von Daten-Ownership, Event-Streaming, Work-Queues | Entkoppelt | Entkoppelt |
🎯 Aufgaben & Checkliste in aufgabe.go
Führe deine Tests immer mit dem Race Detector aus: go test -race ./.... Go instrumentiert den Code und schlägt sofort Alarm, falls ein nebenläufiger ungeschützter Speicherzugriff erkannt wird!