github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/prepare/18channeluse/trylock_channel/main.go (about) 1 package main 2 3 import "fmt" 4 5 type Mutex struct { 6 ch chan struct{} 7 } 8 9 func NewMutex() *Mutex { 10 mu := &Mutex{ 11 ch: make(chan struct{}, 1), 12 } 13 mu.ch <- struct{}{} 14 return mu 15 } 16 17 func (m *Mutex) Lock() { 18 <-m.ch 19 } 20 21 func (m *Mutex) Unlock() { 22 select { 23 case m.ch <- struct{}{}: 24 default: 25 panic("unlock of unlocked mutex") 26 } 27 } 28 29 func (m *Mutex) TryLock() bool { 30 select { 31 case <-m.ch: 32 return true 33 default: 34 } 35 return false 36 } 37 38 func (m *Mutex) IsLocked() bool { 39 return len(m.ch) == 0 40 } 41 42 func main() { 43 m := NewMutex() 44 ok := m.TryLock() 45 fmt.Printf("locked v %v\n", ok) 46 ok = m.TryLock() 47 fmt.Printf("locked %v\n", ok) 48 }