一、Mutex 互斥锁
Lock() // 写的时候 排斥其他的写锁和读锁
Unlock()
package main
import (
"fmt"
"sync"
"time"
)
func main() {
l := &sync.Mutex{}
go lockFunc(l)
go lockFunc(l)
go lockFunc(l)
go lockFunc(l)
for {}
}
func lockFunc(lock *sync.Mutex) {
lock.Lock()
fmt.Println("疯狂刮痧")
time.Sleep(time.Second)
lock.Unlock()
}
我们可以看到输出”疯狂刮痧“是依次打印出来的
二、RWMutex 读写互斥锁
Lock() // 写的时候 排斥其他的写锁和读锁
Unlock()
Rlock() // 在读取的时候,不会阻其他的读锁,但是会排斥掉写锁
Runlock()
package main
import (
"fmt"
"sync"
"time"
)
func main() {
l := &sync.RWMutex{}
go lockFunc(l)
go lockFunc(l)
go lockFunc(l)
go lockFunc(l)
for {}
}
func lockFunc(lock *sync.RWMutex) {
lock.RLock()
fmt.Println("疯狂刮痧")
time.Sleep(time.Second)
lock.RUnlock()
}
我们可以看到输出”疯狂刮痧“是一次打印出来的
三、Once
Once.Do(一个函数) 这个方法无论被调用多少次,这里只会执行一次
package main
import (
"fmt"
"sync"
)
func main() {
o := &sync.Once{}
for i := 1; i <= 10; i++ {
o.Do(func() {
fmt.Println(i)
})
}
}
四、WaitGroup
Add(delta int) 设定需要 Done 多少次
Done() Done一次+1
Wait() 再到达 Done 的次数前一直阻塞
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wg := &sync.WaitGroup{}
wg.Add(2)
go func() {
time.Sleep(time.Second)
wg.Done()
fmt.Println("1")
}()
go func() {
time.Sleep(2 * time.Second)
wg.Done()
fmt.Println("2")
}()
wg.Wait()
fmt.Println("0")
}
五、Map 一个并发字典
Store
Load
package main
import (
"fmt"
"sync"
"time"
)
func main() {
m := &sync.Map{}
go func() {
for {
m.Store(1, 1)
}
}()
go func() {
for {
fmt.Println(m.Load(1))
}
}()
time.Sleep(100)
}
LoadOrStore
Delete
package main
import (
"fmt"
"sync"
)
func main() {
m := &sync.Map{}
m.Store(1, 1)
m.Delete(1)
fmt.Println(m.Load(1))
m.LoadOrStore(1, 1)
fmt.Println(m.Load(1))
}
Range:return true 才会继续往下遍历
package main
import (
"fmt"
"sync"
)
func main() {
m := &sync.Map{}
m.Store(1, 1)
m.Store(2, 2)
m.Range(func(key, value interface{}) bool {
fmt.Println(key, value)
return true
})
}
六、Pool 并发池
Put
Get
package main
import (
"fmt"
"sync"
"time"
)
func main() {
p := &sync.Pool{}
for i := 1; i <= 5; i++ {
p.Put(i)
}
for i := 1; i <= 5; i++ {
time.Sleep(time.Second)
fmt.Println(p.Get())
}
}
七、Cond 没多大用的通知解锁
NewCond (lock) 创建一个 cond
co.L.Lock()
co.L.Unlock0
创建一个锁区间,在区域内部都可以 co.wait()
co.Broadcast() 解锁全部
package main
import (
"fmt"
"sync"
"time"
)
func main() {
co := sync.NewCond(&sync.Mutex{})
flag := false
go func() {
co.L.Lock()
fmt.Println("lock1")
for flag {
co.Wait()
}
fmt.Println("unlock1")
co.L.Unlock()
}()
go func() {
co.L.Lock()
fmt.Println("lock2")
for flag {
co.Wait()
}
fmt.Println("unlock2")
co.L.Unlock()
}()
co.Broadcast()
time.Sleep(time.Second)
}
co.Signal() 解锁一个
package main
import (
"fmt"
"sync"
"time"
)
func main() {
co := sync.NewCond(&sync.Mutex{})
flag := false
go func() {
co.L.Lock()
fmt.Println("lock1")
for flag {
co.Wait()
}
fmt.Println("unlock1")
co.L.Unlock()
}()
go func() {
co.L.Lock()
fmt.Println("lock2")
for flag {
co.Wait()
}
fmt.Println("unlock2")
co.L.Unlock()
}()
time.Sleep(time.Second)
co.Signal()
time.Sleep(time.Second)
co.Signal()
}