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  }