
- Go - Home
- Go - Overview
- Go - Environment Setup
- Go - Program Structure
- Go - Basic Syntax
- Go - Data Types
- Go - Variables
- Go - Constants
- Go - Identifiers
- Go - Keywords
- Go - Operators
- Go - Arithmetic Operators
- Go - Assignment Operators
- Go - Relational Operators
- Go - Logical Operators
- Go - Bitwise Operators
- Go - Miscellaneous Operators
- Go - Operators Precedence
- Go Decision Making
- Go - Decision Making
- Go - If Statement
- Go - If Else Statement
- Go - Nested If Statements
- Go - Switch Statement
- Go - Select Statement
- Go Control Flow Statements
- Go - For Loop
- Go - Nested for Loops
- Go - Break Statement
- Go - Continue Statement
- Go - Goto Statement
- Go Functions
- Go - Functions
- Go - Call by Value
- Go - Call by Reference
- Go - Functions as Values
- Go - Function Closure
- Go - Function Method
- Go - Anonymous function
- Go Strings
- Go - Strings
- Go - String Length
- Go - String Concatenation
- Go - Compare Strings
- Go - Split String
- Go - Substring Extraction
- Go - String Replacement
- Go - String Interpolation
- Go - Parse Date Strings
- Go Arrays
- Go - Arrays
- Go - Multidimensional Arrays
- Go - Multidimensional Arrays
- Go - Passing Arrays to Functions
- Go - Pointers
- Go - Pointers
- Go - Array of pointers
- Go - Pointer to pointer
- Go - Passing pointers to functions
- Go Advanced Control Structures
- Go - Scope Rules
- Go - Dereferencing Pointer
- Go - Structures
- Go - Slice
- Go - Slice of Slices
- Go - Range
- Go - Maps
- Go - Recursion
- Go - Type Casting
- Go - Interfaces
- Go - Type Assertion
- Go - Error Handling
- Go - Concurrency
- Go - Regular Expression
- Go - Inheritance
- Go - Packages
- Go - Templates
- Go - Reflection
- Go - Generics
- Go File Handling
- Go - Read File By Word
- Go - Read File By Line
- Go - Read CSV Files
- Go - Delete File
- Go - Rename & Move File
- Go - Truncate a File
- Go - File Read-Write Mode W/O Truncation
- Go Miscellaneous
- Go - defer Keyword
- Go - Fmt Package
- Go - Zero Value
- Go - Import
Go - Concurrency
In Golang, concurrency refers to powerful built-in support for concurrent programming. This means that multiple tasks can run on their own and even at the same time.
Goroutines
A Goroutine is a thread of execution that's managed by Go's runtime. It is an essential part of Go's concurrency model and enables you to run functions or methods simultaneously with other functions or methods.
It is created using the go keyword. Example: go myFunction(). They have very little overhead and are quite efficient.
Syntax
Following is the syntax for Goroutine of Concurrency in Golang −
go functionName(parameters)
Example
In this example, The sayHello method executes alongside the main function when we use go sayHello(). Using time, the main function stops for one second to give the goroutine enough time to run before the program ends(sleep).
package main import ( "fmt" "time" ) func sayHello() { fmt.Println("Hello goroutine!") } func main() { go sayHello() time.Sleep(time.Second) fmt.Println("Hello main function!") }
When the above code is compiled and executed, it produces the following result −
Hello goroutine! Hello main function!
Go Channels
In Golang, Channels is a powerful feature that allows goroutines to communicate with each other and synchronize their execution.
They provide a way to send and receive values between goroutines, making it easy to build concurrent programs. It is created using the make function.
Syntax
Following is the syntax for the channel of concurrency in golang −
ch := make(chan int) ch := make(chan int, 100)
Use the <- operator to send and receive data.
ch <- data (send) data := <-ch (receive).
Example
In this example, the worker function sleeps for one second and sends the value 42 into the channel. The main function starts the worker as a goroutine, waits to receive the value, and prints the value.
package main import ( "fmt" "time" ) func worker(ch chan int) { time.Sleep(time.Second) ch <- 42 // Send value into channel } func main() { ch := make(chan int) // Create an unbuffered channel go worker(ch) // Start a goroutine value := <-ch // Receive value from channel fmt.Println("Received:", value) }
When the above code is compiled and executed, it produces the following result −
Received: 46
Go Select Statement
In Golang, the select statement is a control structure that allows a goroutine to wait on multiple communication operations (channel operations).
It is similar to a switch statement but designed for channels. The select statement blocks until one of its cases can proceed, then it executes that case.
Syntax
Following is the syntax to the select statement in Golang −
select { case msg := <-ch1: // handle msg from channel 1 case msg := <-ch2: // handle msg from channel 2 }
Example
In this example, the program waits for messages from ch1 and ch2 and display them as they arrive. The select statement ensures that the program can handle whichever message comes first without blocking.
package main import ( "fmt" "time" ) func main() { ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(time.Second) ch1 <- "Message from ch1" }() go func() { time.Sleep(time.Second * 2) ch2 <- "Message from ch2" }() for i := 0; i < 2; i++ { select { case msg1 := <-ch1: fmt.Println(msg1) case msg2 := <-ch2: fmt.Println(msg2) } } }
When the above code is compiled and executed, it produces the following result −
Message from ch1 Message from ch2
Go WaitGroups
A WaitGroup is a synchronization primitive provided by the sync package that allows you to wait for a collection of goroutines to finish executing. It is useful when you need to ensure that multiple goroutines have completed their tasks before continuing with the main program.
Syntax
Following is the syntax for the WaitGroups of concurrency in Golang −
var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() // goroutine work }() wg.Wait()
Example
In this example, the program waits for all worker goroutines to complete their tasks before printing "All workers done". The worker function prints a starting message, sleeps for one second, and then prints a done message.
package main import ( "fmt" "sync" "time" ) func worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("Worker %d starting\n", id) time.Sleep(time.Second) fmt.Printf("Worker %d done\n", id) } func main() { var wg sync.WaitGroup for i := 1; i <= 3; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() fmt.Println("All workers done") }
When the above code is compiled and executed, it produces the following result −
Worker 3 starting Worker 2 starting Worker 1 starting Worker 2 done Worker 3 done Worker 1 done All workers done
Go Mutexes
In Golang, the mutexesis provided by the sync package, are synchronization primitives used to protect shared resources and prevent race conditions when multiple goroutines access and modify those resources concurrently. A Mutex ensures that only one goroutine can access the critical section of code at a time, thus maintaining data integrity.
Syntax
Following is the syntax for the mutexesis of concurrency in Golang −
var mu sync.Mutex mu.Lock() // critical section mu.Unlock()
Example
In this example, the mutex mu ensures that the counter variable is incremented safely by multiple goroutines, preventing race conditions.
package main import ( "fmt" "sync" ) var ( counter int mu sync.Mutex ) func increment(wg *sync.WaitGroup) { defer wg.Done() mu.Lock() counter++ mu.Unlock() } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Counter:", counter) }
When the above code is compiled and executed, it produces the following result −
Counter: 5