Can I use *sync.Mutex as an object specific variable?

Issue

I want to make my program more efficient:
can I give a *sync.Mutex variable to a struct so that when I execute a obj.Mutex.Lock() it is locking just goroutines operation on that specific object?

example:

package main

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

type mystruct struct {
    Counter int
    Mutex   *sync.Mutex
}

func (obj *mystruct) incrementCount() {
    for i := 0; i < 1000; i++ {
        obj.Mutex.Lock()
        obj.Counter++
        time.Sleep(time.Microsecond)
        obj.Mutex.Unlock()
    }
    fmt.Println("incrementCount returns")
}

func funcNotSensibleToMutex() {
    n := 0
    for i := 0; i < 1000; i++ {
        n++
        time.Sleep(time.Microsecond)
    }
    fmt.Println("returns first since it's not affected by mutex")
}

func main() {
    a := &mystruct{0, &sync.Mutex{}}
    go a.incrementCount()
    go a.incrementCount()
    go funcNotSensibleToMutex()

    time.Sleep(time.Duration(5) * time.Second)
    fmt.Println("a counter", a.Counter)
}

Solution

because whenever I set a Lock on any mutex all variables are Locked?

That wouldn’t make any sense. A mutex holds the locking state. Calling its Lock() and Unlock() methods synchronize goroutines based on its state. Separate mutex values have separate, distinct states.

It’s completely normal and common to add mutex to a struct, you may even embed it: When do you embed mutex in struct in Go? The effect is what you’d expect: the mutex can be used to protect concurrent access to the containing struct value, but other struct values are not effected. 2 concurrent goroutines may update 2 separate struct values, but no more than 1 goroutine will access the same struct value at the same time.

Answered By – icza

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.