~kotrunga/a-tour-of-go

a-tour-of-go/concurrency/3.9_mutex-counter.go -rw-r--r-- 1.2 KiB View raw
b3f98925kotrunga remove .DS_Store file 8 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
	Notes 3.9

	'mutual exclusion'- allowing goroutines to only access a variable one at a time
	to prevent conflicts. Uses the data structure called a 'mutex'

	Go's standard lib provides mutual exclusion via sync.Mutex (has methods Lock and Unlock).

	We can execute a block of code in mutual exclusion by surrounding it with Lock and Unlock
	(see the Inc method).

	You can also use the defer method to ensure the mutex is unlocked (see the Value method).
*/

package main

import (
	"fmt"
	"sync"
	"time"
)

// SafeCounter is safe to use concurrently.
type SafeCounter struct {
	v   map[string]int
	mux sync.Mutex
}

// Inc increments the counter for the given key.
func (c *SafeCounter) Inc(key string) {
	c.mux.Lock()
	// Lock so only one goroutine at a time can access the map c.v.
	c.v[key]++
	c.mux.Unlock()
}

// Value returns the current value of the counter for the given key.
func (c *SafeCounter) Value(key string) int {
	c.mux.Lock()
	// Lock so only one goroutine at a time can access the map c.v.
	defer c.mux.Unlock()
	return c.v[key]
}

func main() {
	c := SafeCounter{v: make(map[string]int)}
	for i := 0; i < 1000; i++ {
		go c.Inc("somekey")
	}

	time.Sleep(time.Second)
	fmt.Println(c.Value("somekey"))
}