1)目录
|____go.mod
|____atomic
| |____impl
| | |____lockcounter.go
| | |____counter.go
| | |____atomiccounter.go
| | |____nonlockcounter.go
| |____main.go
|____synconce
| |____main.go
|____rwmutex
| |____main.go
|____normalmap
| |____main.go
|____mutex
| |____main.go
|____syncmap
| |____main.go
2)实现
|____go.mod
module github.com/jianan/demo
go 1.13
|____atomic
| |____impl
| | |____lockcounter.go
package impl
import "sync"
type LockCounter struct {
val int64
lock sync.Mutex
}
func (l *LockCounter) Increment() {
l.lock.Lock()
defer l.lock.Unlock()
l.val++
}
func (l *LockCounter) Load() int64 {
l.lock.Lock()
defer l.lock.Unlock()
return l.val
}
| | |____counter.go
package impl
type Counter interface {
Increment()
Load() int64
}
| | |____atomiccounter.go
package impl
import "sync/atomic"
type AtomicCounter struct {
val int64
}
func (a *AtomicCounter) Increment() {
atomic.AddInt64(&a.val, 1)
}
func (a *AtomicCounter) Load() int64 {
return atomic.LoadInt64(&a.val)
}
| | |____nonlockcounter.go
package impl
type NonLockCounter struct {
val int64
}
func (n *NonLockCounter) Increment() {
n.val++
}
func (n *NonLockCounter) Load() int64 {
return n.val
}
| |____main.go
package main
import (
"fmt"
"github.com/jianan/demo/atomic/impl"
"sync"
"time"
)
func test(c impl.Counter) {
wg := sync.WaitGroup{}
start := time.Now()
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
c.Increment()
wg.Done()
}()
}
wg.Wait()
end := time.Now()
fmt.Println(c.Load(), end.Sub(start))
}
func main() {
c1 := impl.NonLockCounter{}
c2 := impl.LockCounter{}
c3 := impl.AtomicCounter{}
test(&c1)
test(&c2)
test(&c3)
}
/*
953 617.268µs
1000 282.257µs
1000 244.219µs
*/
|____synconce
| |____main.go
package main
import (
"fmt"
"sync"
)
var (
instance *singleton
// 只会执行一次
// 可用于单例模式的实现
once sync.Once
)
type singleton struct {
}
func GetInstance() *singleton {
once.Do(func() {
fmt.Println("实例化")
instance = &singleton{}
})
once.Do(func() {
fmt.Println("实例化")
instance = &singleton{}
})
return instance
}
func main() {
GetInstance()
}
/*
实例化
*/
|____rwmutex
| |____main.go
package main
import (
"fmt"
"sync"
"time"
)
var (
wg sync.WaitGroup
lock sync.RWMutex // 1.350057954s
// 读写锁,适用于读多写少的情况,性能提升10倍+
rwlock sync.RWMutex // 110.416132ms
)
func write() {
rwlock.Lock()
time.Sleep(10 * time.Millisecond)
rwlock.Unlock()
wg.Done()
}
func read() {
//lock.Lock()
rwlock.RLock()
time.Sleep(time.Millisecond)
rwlock.RUnlock()
//lock.Unlock()
wg.Done()
}
func main() {
start := time.Now()
for i := 0; i < 10; i++ {
wg.Add(1)
go write()
}
for i := 0; i < 1000; i++ {
wg.Add(1)
go read()
}
wg.Wait()
end := time.Now()
fmt.Println(end.Sub(start))
}
|____normalmap
| |____main.go
package main
import (
"fmt"
"strconv"
"sync"
)
var (
// 并发的map
safeMap = make(map[string]int)
)
func main() {
wg := sync.WaitGroup{}
for i := 0; i < 20; i++ {
go func(n int) {
wg.Add(1)
key := strconv.Itoa(n)
safeMap[key] = n
val, ok := safeMap[key]
if ok {
fmt.Println("key:", key, "val:", val)
}
wg.Done()
}(i)
}
wg.Wait()
}
/*
runtime.throw(0x10d291e, 0x15)
/usr/local/go/src/runtime/panic.go:774 +0x72 fp=0xc00002e6b8 sp=0xc00002e688 pc=0x1029332
runtime.mapassign_faststr(0x10b2040, 0xc00008a030, 0x10d5530, 0x1, 0x0)
/usr/local/go/src/runtime/map_faststr.go:211 +0x417 fp=0xc00002e720 sp=0xc00002e6b8 pc=0x1010467
main.main.func1(0xc000088004, 0x3)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:21 +0x94 fp=0xc00002e7d0 sp=0xc00002e720 pc=0x10995e4
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc00002e7d8 sp=0xc00002e7d0 pc=0x10530e1
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 1 [runnable]:
sync.(*WaitGroup).Wait(0xc000088004)
/usr/local/go/src/sync/waitgroup.go:103 +0xb3
main.main()
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:30 +0x7f
goroutine 18 [runnable]:
fmt.(*pp).doPrintln(0xc0000a00d0, 0xc000066f80, 0x4, 0x4)
/usr/local/go/src/fmt/print.go:1168 +0x1e1
fmt.Fprintln(0x10eb2c0, 0xc000080000, 0xc000066f80, 0x4, 0x4, 0x1, 0x0, 0x0)
/usr/local/go/src/fmt/print.go:264 +0x58
fmt.Println(...)
/usr/local/go/src/fmt/print.go:274
main.main.func1(0xc000088004, 0x0)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:24 +0x1f1
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 19 [runnable]:
main.main.func1(0xc000088004, 0x1)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 20 [runnable]:
main.main.func1(0xc000088004, 0x2)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 22 [runnable]:
main.main.func1(0xc000088004, 0x4)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:24 +0x142
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 23 [runnable]:
main.main.func1(0xc000088004, 0x5)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 24 [runnable]:
main.main.func1(0xc000088004, 0x6)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 25 [runnable]:
main.main.func1(0xc000088004, 0x7)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 26 [runnable]:
main.main.func1(0xc000088004, 0x8)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 27 [runnable]:
main.main.func1(0xc000088004, 0x9)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 28 [runnable]:
main.main.func1(0xc000088004, 0xa)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 29 [runnable]:
main.main.func1(0xc000088004, 0xb)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 30 [runnable]:
main.main.func1(0xc000088004, 0xc)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 31 [runnable]:
main.main.func1(0xc000088004, 0xd)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 32 [runnable]:
main.main.func1(0xc000088004, 0xe)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 33 [runnable]:
main.main.func1(0xc000088004, 0xf)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 34 [runnable]:
main.main.func1(0xc000088004, 0x10)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 35 [runnable]:
main.main.func1(0xc000088004, 0x11)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 36 [runnable]:
main.main.func1(0xc000088004, 0x12)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
goroutine 37 [runnable]:
main.main.func1(0xc000088004, 0x13)
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18
created by main.main
/Users/jianan/Documents/my_git/go_module/GoDemo/normalmap/main.go:18 +0x62
Process finished with exit code 2
*/
|____mutex
| |____main.go
package main
import (
"fmt"
"sync"
)
var (
// 共享变量
global int64
// 用于指定多少个任务
wg sync.WaitGroup
// 互斥锁
lock sync.Mutex
)
func add() {
defer wg.Done()
for i := 0; i < 5000; i++ {
lock.Lock()
global++
lock.Unlock()
}
}
func main() {
// 任务数量
taskNum := 10
wg.Add(taskNum)
for i := 0; i < taskNum; i++ {
go add()
}
wg.Wait()
fmt.Println(global)
}
|____syncmap
| |____main.go
package main
import (
"fmt"
"strconv"
"sync"
)
var (
// 并发的map
safeMap = sync.Map{}
)
func main() {
wg := sync.WaitGroup{}
for i := 0; i < 20; i++ {
go func(n int) {
wg.Add(1)
key := strconv.Itoa(n)
safeMap.Store(key, n)
val, ok := safeMap.Load(key)
if ok {
fmt.Println("key:", key, "val:", val)
}
wg.Done()
}(i)
}
wg.Wait()
}
/*
key: 3 val: 3
key: 1 val: 1
key: 0 val: 0
key: 8 val: 8
key: 5 val: 5
key: 6 val: 6
key: 7 val: 7
key: 4 val: 4
key: 10 val: 10
key: 9 val: 9
key: 11 val: 11
key: 12 val: 12
key: 13 val: 13
key: 14 val: 14
key: 15 val: 15
key: 16 val: 16
key: 17 val: 17
key: 18 val: 18
key: 2 val: 2
key: 19 val: 19
*/
来源:oschina
链接:https://my.oschina.net/u/4353583/blog/4479284