> For the complete documentation index, see [llms.txt](https://davidwinalda94.gitbook.io/mastering-golang/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://davidwinalda94.gitbook.io/mastering-golang/concurrency-mutex.md).

# Concurrency - Mutex

Sebelum membahan tentang Mutex, ada hal penting di dalam concurrent programming. Ketika program berjalan secara concurrent, tidak boleh terjadi lebih dari satu goroutine, mengakses data yang sama pada waktu yang bersamaan (benar-benar bersamaan). Ketika hal ini terjadi, nilai data tersebut akan menjadi kacau dan conflict.

Misalnya kita ingin melakukan proses counter dimulai dari initial value `0` dan bertambah `1` setiap perulangan dimana hasil akhirnya adalah `1000` .

```
x = x + 1
```

Jika program di atas dijalankan oleh lebih dari 1 goroutine maka kemungkinan yang akan terjadi adalah sebagai berikut:

![source: https://golangbot.com/mutex/](https://2969676661-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQaVepPFjuLoNjbs6f8%2F-MTAs2AS7kxbR_g0W27X%2F-MTAwBTecevHPSgdxjtF%2Fcs5.png?alt=media\&token=ea20b895-a5f7-40be-b7eb-d69b556cd11c)

Mari kita lihat contoh kasus berikut ini dimana akan dijalankan oleh 1000 goroutine tanpa menggunakan Mutex:

```go
package main  

import (  
    "fmt"
    "sync"
    )
var x  = 0  

func increment(wg *sync.WaitGroup) {  
    x = x + 1
    wg.Done()
}

func main() {  
    var w sync.WaitGroup
    for i := 0; i < 1000; i++ {
        w.Add(1)        
        go increment(&w)
    }
    w.Wait()
    fmt.Println("final value of x", x)
}
```

![Terjadi perbedaan nilai setiap program di jalankan](https://2969676661-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQaVepPFjuLoNjbs6f8%2F-MTAs2AS7kxbR_g0W27X%2F-MTAwvuG-ExsZZAMtoq9%2FScreen%20Shot%202021-02-10%20at%2019.38.53.png?alt=media\&token=ae465da0-78b6-40cd-9383-ab7690c105e9)

### Menggunakan Mutex

Mari kita menggunakan Mutex untuk menyelesaikan kasus di atas.&#x20;

```go
package main  

import (  
    "fmt"
    "sync"
)

var x  = 0  

func increment(wg *sync.WaitGroup, m *sync.Mutex) {  
    m.Lock()
    x = x + 1
    m.Unlock()
    wg.Done()   
}

func main() {  
    var w sync.WaitGroup
    var m sync.Mutex
    
    for i := 0; i < 1000; i++ {
        w.Add(1)        
        go increment(&w, &m)
    }
    
    w.Wait()
    fmt.Println("final value of x", x)
}
```

[Mutex](https://golang.org/pkg/sync/#Mutex) adalah sebuah tipe data. Pada kode di atas kita membuat a zero value pada variabel `m` yang bertipe `Mutex` pada baris kode ke-15. Kita mengubah behaviour pada fungsi `increment` sehingga kode `x = x + 1` berada diantara `m.Lock()` and `m.Unlock()`. Ini membuat hanya 1 goroutine yang bisa menjalankan statement tersebut dalam 1 waktu.

![Menjalankan program dengan Mutex](https://2969676661-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MQaVepPFjuLoNjbs6f8%2F-MTAs2AS7kxbR_g0W27X%2F-MTAybUMwojj9ofdE1lM%2FScreen%20Shot%202021-02-10%20at%2019.46.14.png?alt=media\&token=d9946ca7-6df7-4a24-baa8-5e85973894c6)
