sync.WaitGroup(计数器)
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
func randNum(){
rand.Seed(time.Now().UnixNano())
for i := 0; i < 100; i++ {
a := rand.Int()
b := rand.Intn(10)
fmt.Println(a,b)
}
}
var wg sync.WaitGroup
func main() {
for i := 0; i < 10; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
//如何知道写成社么时间结束
time.Sleep(time.Second*time.Duration(rand.Intn(10)))
fmt.Println(i)
}(i)
}
wg.Wait()//等带计数器结束
fmt.Println("22222")
}
sync.Mutex(互斥锁)
package main
import (
"fmt"
"sync"
)
func add() {
for i := 0; i < 5000; i++ {
lock.Lock()
v++
lock.Unlock()
}
wg.Done()
}
var v int
//计时器
var wg sync.WaitGroup
//互斥锁
var lock sync.Mutex
//读写锁,读锁可以多个人同时获取,写锁智能一个人获取。当有人获取写锁进行写操作时,读锁和写锁都要进行等待
var rwLock sync.RWMutex
func main() {
wg.Add(2)
go add()
go add()
wg.Wait()
fmt.Println(v)
}
sync.RWMutex(读写锁)
package main
import (
"fmt"
"sync"
"time"
)
var v int
//计时器
var wg sync.WaitGroup
//互斥锁
var lock sync.Mutex
//读写锁,读锁可以多个人同时获取,写锁智能一个人获取。当有人获取写锁进行写操作时,读锁和写锁都要进行等待
var rwLock sync.RWMutex
func write() {
rwLock.Lock()
fmt.Println(v)
v++
rwLock.Unlock()
wg.Done()
}
func read() {
rwLock.RLock()
fmt.Println(v)
rwLock.RUnlock()
wg.Done()
}
func main() {
start := time.Now()
for i := 0; i < 100; i++ {
go write()
wg.Add(1)
}
for i := 0; i < 1000; i++ {
go read()
wg.Add(1)
}
wg.Wait()
fmt.Println(time.Now().Sub(start))
}
sync.Once(高并发下某个操作只做一次)
package main
import (
"fmt"
"sync"
"time"
)
var v int
//计时器
var wg sync.WaitGroup
//互斥锁
var lock sync.Mutex
var once sync.Once
func write() {
once.Do(func() {
v = 100
})
lock.Lock()
v++
lock.Unlock()
wg.Done()
}
func main() {
start := time.Now()
wg.Add(100)
for i := 0; i < 100; i++ {
go write()
}
wg.Wait()
//最总v的结果为200
fmt.Println(v)
fmt.Println(time.Now().Sub(start))
}
sync.Map(并发map包)
package main
import (
"fmt"
"strconv"
"sync"
)
var v int
//计时器
var wg sync.WaitGroup
//互斥锁
var lock sync.Mutex
var once sync.Once
//内置的map不是并发安全的
var m1 = sync.Map{}
var m2 = make(map[string]string)
func main() {
wg.Add(100)
for i := 0; i < 100; i++ {
go func(i int) {
key := strconv.Itoa(i)
m1.Store(key, key)
value, _ := m1.Load(key)
fmt.Println(value)
wg.Done()
}(i)
}
wg.Wait()
wg.Add(100)
//普通map最多只支持20个goroutine去并发修改,如果超过20会引发panic,需要加锁解决该问题,
//go提供了sync.map来解决此问题
for i := 0; i < 100; i++ {
go func(i int) {
key := strconv.Itoa(i)
m2[key] = key
value := m2[key]
fmt.Println(value)
wg.Done()
}(i)
}
wg.Wait()
}