Home > Backend Development > Golang > How to Achieve Thread Safety in Go: Mutexes, Atomics, or Channels?

How to Achieve Thread Safety in Go: Mutexes, Atomics, or Channels?

Mary-Kate Olsen
Release: 2024-12-18 22:14:10
Original
304 people have browsed it

How to Achieve Thread Safety in Go: Mutexes, Atomics, or Channels?

How to Implement Thread-Safety for Variables in Go

In Java, the concept of synchronized variables ensures that only a single thread can execute a specific code block at any given time. However, Go does not offer an explicit synchronized keyword.

Rationale

Go promotes a different approach to thread synchronization, guided by the principle: "Do not communicate by sharing memory; instead, share memory by communicating." This means avoiding direct access to shared memory and opting for communication-based mechanisms like channels.

Mutex-Based Synchronization

Should you encounter a scenario where a mutex is necessary, here's how to implement it in Go:

var (
    mu        sync.Mutex
    protectMe int
)

func getMe() int {
    mu.Lock()
    me := protectMe
    mu.Unlock()
    return me
}

func setMe(me int) {
    mu.Lock()
    protectMe = me
    mu.Unlock()
}
Copy after login

Improvements

  • Convert sync.Mutex to sync.RWMutex to enable concurrent read access.
  • Consider using defer to avoid resource leaks in case of errors.
  • Embed the mutex within the protected value to enhance code readability and convenience.

Atomic Synchronization

If you need to protect a single value, consider using the sync/atomic package:

var protectMe int32

func getMe() int32 {
    return atomic.LoadInt32(&protectMe)
}

func setMe(me int32) {
    atomic.StoreInt32(&protectMe, me)
}
Copy after login

Communication-Based Approach

Go encourages using channels for inter-goroutine communication, eliminating the need for shared variables. For example, in a publisher-subscriber pattern:

type topic struct {
    subscribing []chan int
}

var t = &topic{}

func subscribe() chan int {
    ch := make(chan int)
    t.subscribing = append(t.subscribing, ch)
    return ch
}

func publish(v int) {
    for _, ch := range t.subscribing {
        ch <- v
    }
}
Copy after login

This approach ensures thread-safe communication without sharing memory.

The above is the detailed content of How to Achieve Thread Safety in Go: Mutexes, Atomics, or Channels?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template