Что такое пессимистичная блокировка и как она реализуется в Go? Расскажите о своем опыте ее использования.

Ответ

Пессимистичная блокировка — это стратегия управления параллельным доступом, при которой ресурс блокируется перед использованием, чтобы предотвратить конфликты. Она исходит из предположения, что конфликты доступа вероятны.

В Go пессимистичная блокировка реализуется с помощью примитивов синхронизации из пакета sync:

  • sync.Mutex: Обеспечивает эксклюзивную блокировку. Только одна горутина может владеть мьютексом в любой момент времени.
  • sync.RWMutex: Блокировка с разделением на чтение и запись. Позволяет неограниченному числу горутин одновременно читать данные, но запись требует эксклюзивной блокировки.

Простой пример с sync.Mutex:

package main

import (
    "fmt"
    "sync"
)

var (
    counter int
    mu      sync.Mutex
    wg      sync.WaitGroup
)

// increment безопасно увеличивает счетчик
func increment() {
    defer wg.Done()
    mu.Lock() // Захватываем блокировку
    defer mu.Unlock() // Гарантируем освобождение блокировки
    counter++
}

func main() {
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go increment()
    }
    wg.Wait()
    fmt.Println("Final counter:", counter) // => Final counter: 1000
}

Когда использовать:
Пессимистичные блокировки эффективны в сценариях с высокой вероятностью конфликтов (high contention), когда несколько горутин часто пытаются изменить одни и те же данные.

Преимущества:

  • Простота: Легко реализовать и понять.
  • Надежность: Гарантирует защиту от гонок данных (data races).

Недостатки:

  • Производительность: Может стать узким местом, так как горутины простаивают в ожидании освобождения блокировки.
  • Риск Deadlock: Неправильное управление несколькими мьютексами (например, разный порядок захвата) может привести к взаимной блокировке.