12/04/2026 18:16pm

Ep.18 Go and Concurrency: Doing Multiple Things Smoothly!
#Superdev School
#programmers
#programming language
#programming technology
#programming for beginners
#programming development
#Programming Education
#Practice programming
#Channels
#Goroutines
#Concurrency
#Golang
#Go language
Go and Concurrency: Doing Multiple Things Smoothly!
What is Concurrency?
Concurrency is the ability to perform multiple tasks simultaneously without waiting for each task to complete one after another. For example, loading data while waiting for a response from a server. In Go, we have Goroutines that make managing concurrency easier.
Working with Goroutines
Goroutines are functions in Go that operate in the background. When we call a function with the keyword go, that function starts running as a Goroutine immediately without blocking the main program.
Example of using Goroutine:
In this example, the printNumbers function will run as a Goroutine, operating in the background without blocking main().
package main
import (
"fmt"
"time"
)
func printNumbers() {
for i := 1; i <= 5; i++ {
fmt.Println(i)
time.Sleep(500 * time.Millisecond)
}
}
func main() {
go printNumbers() // เริ่ม Goroutine
fmt.Println("Goroutine started")
time.Sleep(3 * time.Second) // รอให้ Goroutine ทำงานเสร็จ
}
Communicating Between Goroutines Using Channels
Channels are tools for sending data between Goroutines, allowing us to control the operations of Goroutines and send data back and forth.
Example of using Channel:
In this example:
ch := make(chan string) creates a Channel for sending string data.
ch <- "Hello from Goroutine" sends a message from the Goroutine to the Channel.
msg := <-ch receives the message from the Channel and prints it out.
package main
import (
"fmt"
)
func printMessage(ch chan string) {
ch <- "Hello from Goroutine" // ส่งข้อความผ่าน Channel
}
func main() {
ch := make(chan string)
go printMessage(ch)
msg := <-ch // รับข้อความจาก Channel
fmt.Println(msg)
}
Buffered Channels - Storing Multiple Values Before Use
Buffered Channels allow us to send multiple values into a Channel before using them, improving efficiency and reducing data queuing.
Example of using Buffered Channel:
In this example:
The Channel ch is created to hold 3 values.
All data will be sent into the Channel and retrieved one value at a time without queuing.
package main
import (
"fmt"
)
func main() {
ch := make(chan int, 3) // Channel ที่เก็บข้อมูลได้ 3 ค่า
ch <- 1
ch <- 2
ch <- 3
fmt.Println(<-ch) // แสดงค่า 1
fmt.Println(<-ch) // แสดงค่า 2
fmt.Println(<-ch) // แสดงค่า 3
}
Using Select to Manage Multiple Channels
When we have multiple Channels, select helps us manage communication between Channels more easily.
Example of using select with Channel:
In this example:
The program will wait until data from any one of the Channels is available.
select allows us to manage data transmission between multiple Channels efficiently.
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(2 * time.Second)
ch1 <- "Message from channel 1"
}()
go func() {
time.Sleep(1 * time.Second)
ch2 <- "Message from channel 2"
}()
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}
In Summary
- Use go to start a Goroutine running in the background.
- Use Channels to send data between Goroutines.
- Use Buffered Channels to store multiple values before use.
- Use select to manage operations between multiple Channels.
Try creating a program that uses Goroutines and Channels to simulate receiving messages from multiple users, while storing the received messages in a Channel and displaying the results one by one in order!