Метод sync.Mutex.TryLock

Метод sync.Mutex.TryLock позволяет попытаться захватить мьютекс без блокировки. В отличие от метода Lock, который блокирует выполнение горутины до освобождения мьютекса, TryLock возвращает true, если захват мьютекса удался, и false, если мьютекс уже заблокирован другой горутиной. Метод не принимает никаких параметров и возвращает булево значение.

Синтаксис

govar mu sync.Mutex
ok := mu.TryLock()

Пример

Давайте попробуем захватить свободный мьютекс методом TryLock:

gopackage main

import (
  "fmt"
  "sync"
)

func main() {
  var mu sync.Mutex

  ok := mu.TryLock()
  fmt.Println(ok)

  mu.Unlock()
}

Результат выполнения кода:

gotrue

Пример

Теперь попробуем захватить уже заблокированный мьютекс методом TryLock:

gopackage main

import (
  "fmt"
  "sync"
  "time"
)

func main() {
  var mu sync.Mutex

  mu.Lock()

  go func() {
    time.Sleep(100 * time.Millisecond)
    mu.Unlock()
  }()

  ok := mu.TryLock()
  fmt.Println(ok)
}

Результат выполнения кода:

gofalse

Пример

Рассмотрим практический пример использования TryLock в циклическом опросе:

gopackage main

import (
  "fmt"
  "sync"
  "time"
)

func main() {
  var mu sync.Mutex
  counter := 0

  // Захватываем мьютекс в другой горутине
  go func() {
    mu.Lock()
    time.Sleep(2 * time.Second)
    counter = 42
    mu.Unlock()
  }()

  // Пытаемся захватить мьютекс каждые 500 мс
  for i := 0; i < 5; i++ {
    if mu.TryLock() {
      fmt.Printf("try %d: mutex locked, counter = %d\n", i, counter)
      mu.Unlock()
      break
    }
    fmt.Printf("try %d: mutex busy\n", i)
    time.Sleep(500 * time.Millisecond)
  }
}

Результат выполнения кода:

go"try 0: mutex busy"
"try 1: mutex busy"
"try 2: mutex busy"
"try 3: mutex locked, counter = 42"

Смотрите также

  • метод sync.Mutex.Lock,
    который блокирует выполнение до захвата мьютекса
  • метод sync.Mutex.Unlock,
    который освобождает захваченный мьютекс
  • метод sync.RWMutex.TryLock,
    который пытается захватить мьютекс для записи без блокировки
  • метод sync.RWMutex.TryRLock,
    который пытается захватить мьютекс для чтения без блокировки