Golang(Go语言)因其高效的并发处理能力,被广泛应用于各种系统中。自从1.11版本发布以来,Go语言的并发模式更加丰富和强大。以下将通过5个经典案例,带领大家深入理解并掌握Golang的并发模式,提升编程技巧。
案例一:Goroutine的创建与启动
Goroutine是Go语言并发编程的核心。以下是一个简单的示例,展示如何创建和启动一个Goroutine:
package main
import (
"fmt"
"time"
)
func sayHello() {
for {
fmt.Println("Hello from Goroutine!")
time.Sleep(time.Second)
}
}
func main() {
go sayHello() // 启动一个Goroutine
fmt.Println("Hello from main!")
time.Sleep(10 * time.Second)
}
在这个案例中,sayHello 函数在一个新的Goroutine中无限循环打印消息。main 函数中启动了这个Goroutine,并等待10秒钟后退出。
案例二:通道(Channel)的使用
通道是Goroutine之间通信的方式。以下是一个使用通道的示例:
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan bool)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(i)
time.Sleep(time.Second)
}
done <- true // 通知main函数任务完成
}()
<-done // 等待任务完成
fmt.Println("All done!")
}
在这个案例中,一个Goroutine负责打印数字,另一个Goroutine等待它完成任务。使用通道done进行通信。
案例三:带缓冲的通道
带缓冲的通道在发送和接收时可以缓存数据,以下是一个使用带缓冲通道的示例:
package main
import (
"fmt"
"time"
)
func main() {
bufferedChan := make(chan int, 5) // 创建一个带缓冲的通道
for i := 0; i < 10; i++ {
bufferedChan <- i // 发送数据到通道
time.Sleep(time.Second)
}
close(bufferedChan) // 关闭通道
for i := 0; i < 10; i++ {
fmt.Println(<-bufferedChan) // 从通道接收数据
}
}
在这个案例中,带缓冲的通道可以存储5个整数,当通道满时,发送操作会阻塞直到有空间。
案例四:Select语句与多个通道
Select语句可以同时等待多个通道操作。以下是一个使用Select语句的示例:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(2 * time.Second)
ch1 <- "Hello"
}()
go func() {
time.Sleep(1 * time.Second)
ch2 <- "World"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}
}
在这个案例中,Select 语句同时等待两个通道的数据,并打印出收到的消息。
案例五:WaitGroup的使用
WaitGroup用于等待一组Goroutine执行完成。以下是一个使用WaitGroup的示例:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(2) // 增加等待的Goroutine数量
go func() {
defer wg.Done()
for i := 0; i < 3; i++ {
fmt.Println("Goroutine 1")
time.Sleep(time.Second)
}
}()
go func() {
defer wg.Done()
for i := 0; i < 3; i++ {
fmt.Println("Goroutine 2")
time.Sleep(time.Second)
}
}()
wg.Wait() // 等待所有Goroutine执行完成
fmt.Println("All Goroutines completed.")
}
在这个案例中,WaitGroup 用于确保两个Goroutine都执行完成后再退出程序。
通过以上5个经典案例,相信大家对Golang的并发模式有了更深入的理解。不断实践和探索,你会在这个领域取得更大的进步。
