Logo

dev-resources.site

for different kinds of informations.

Achieving High-Level Atomic Operations in Go

Published at
10/12/2023
Categories
go
efficiency
abstraction
programming
Author
ashevelyov
Author
10 person written this
ashevelyov
open
Achieving High-Level Atomic Operations in Go

Achieving High-Level Atomic Operations in Go

Go offers first-class support for concurrency, but mastering the art of concurrent programming involves intricate challenges. One of the most critical tasks is managing shared state across multiple Goroutines, and that's where atomic operations come into play. The Go standard library provides a range of low-level atomic operations that can be leveraged to build thread-safe applications. However, these operations often require a deep understanding of memory models and can be cumbersome to implement. In this article, we explore how to perform high-level atomic operations using the go.uber.org/atomic package, making it easier to write safe and maintainable Go code.

The Scenario

Let's consider a real-world example involving a shared bank balance, a common scenario in financial software. Multiple threads or Goroutines may need to read or update this balance concurrently. While Go's standard library provides atomic operations to manage such shared state, it often lacks higher-level abstractions, which can make the code harder to read and maintain. That's where the go.uber.org/atomic package comes in handy.

package main

import (
    "fmt"
    "go.uber.org/atomic"
)

var balance atomic.Int64

func updateBalance(minAmount int64, change int64) bool {
    for {
        // Load current balance atomically
        currentBalance := balance.Load()

        // Check if balance is greater than minAmount
        if currentBalance < minAmount {
            return false
        }

        // Calculate new balance
        newBalance := currentBalance + change

        // Try to update balance atomically
        if balance.CompareAndSwap(currentBalance, newBalance) {
            return true
        }
    }
}

func main() {
    balance.Store(100)
    success := updateBalance(50, -20)
    fmt.Println("Operation Successful:", success)
    fmt.Println("Updated Balance:", balance.Load())
}
Enter fullscreen mode Exit fullscreen mode

How It Works

Atomic Loading and Storing

The balance.Load() and balance.Store(100) methods are examples of atomic operations that safely load and store the value of the balance variable. These operations ensure that the value of balance can be read or written safely, without being interrupted or accessed simultaneously by another Goroutine, thanks to the atomic methods provided by the go.uber.org/atomic package.

Compare and Swap: The Cornerstone of Atomicity

The CompareAndSwap method is the workhorse of our atomic operations. This method takes two arguments: the expected current value and the new value to set. It atomically checks if the current value matches the expected value and, if so, sets it to the new value. This operation is atomic, meaning it's done in a single, uninterruptible step, ensuring that no other Goroutine can change the balance in the middle of the update.

This replaces the CAS method we used earlier. While CAS offered similar functionality, CompareAndSwap is more idiomatic and aligns better with Go's naming conventions, making the code easier to understand.

Why go.uber.org/atomic?

You might wonder why not stick with Go's built-in atomic package? The go.uber.org/atomic package offers a more ergonomic API and additional type-safety, making it easier to write correct concurrent code. It provides a cleaner, more intuitive interface for dealing with atomic operations, as you can see from our example.

Managing shared state in a concurrent application is a complex but crucial aspect of Go programming. While Go's standard library offers low-level atomic operations, the go.uber.org/atomic package provides a higher level of abstraction, making it easier to write, read, and maintain concurrent code. By understanding and leveraging these atomic operations, you can write more robust and efficient Go applications.

efficiency Article's
30 articles in total
Favicon
Top 10 Books for Boosting Efficiency, Productivity, and Performance
Favicon
How Automation in DevOps Minimizes Human Errors and Boosts Efficiency
Favicon
Streamlining Supply Chains: How Incident Response and Automation Platforms Transform Logistics
Favicon
IntelliJ Shortcuts (for Mac)
Favicon
Enhancing Your Batch Processing System: Strategies for Efficiency and Scalability
Favicon
Empowering Ops Teams Driving Efficiency and Stability
Favicon
Leadership in the Balance - Navigating Execution and Innovation
Favicon
Maximizing Efficiency and Collaboration with Gig Workers
Favicon
PDF Scan File Size: What To Do About It.
Favicon
Benefits of Training & Development for Employees
Favicon
Boost Your Efficiency with the Ultimate Awesome Efficiency List
Favicon
Unlocking Efficiency And Engagement: Workday’s Latest Innovations In 2024R1 Release
Favicon
50% Faster App Development: The Power of Partnering with Us
Favicon
What Can We Achieve with Artificial Intelligence in Customer Service?
Favicon
Unleashing Efficiency: The Power of DevOps Automation in Modern Software Development
Favicon
How IoT is Transforming Construction Site Safety and Efficiency
Favicon
Design It Practical and Simple (DIPS)
Favicon
Understanding LoRA - Low-Rank Adaptation for Efficient Machine Learning
Favicon
Are You Wasting Money in Your Software Development Project?
Favicon
Eat That Frog Method: The Ultimate Guide to Boosting Productivity
Favicon
Effective Branch Management Strategies with Git
Favicon
Big O Notation
Favicon
Exploring the depths of Java's Stream API
Favicon
Dive into optimizing Node.js applications for speed and efficiency.
Favicon
Azure Monitor Parte Final: Dica para alcançar a Eficiência De Desempenho de VMs no Azure
Favicon
Empowering Efficiency: Exploring the World of Codeless Automation
Favicon
Speed Meets Efficiency: Revolutionizing AI with Faster, Lighter Diffusion Models
Favicon
Node.js Worker Threads Vs. Child Processes: Which one should you use?
Favicon
Achieving High-Level Atomic Operations in Go
Favicon
Revolutionizing Testing Efficiency: Embrace Regression Testing Seamless Automation

Featured ones: