七叶笔记 » golang编程 » Golang并发编程,3、解决协程冲突的方案

Golang并发编程,3、解决协程冲突的方案

Go routine是Go并行设计的核心,作为Go中最基本的执行单元,goroutine比thread更易用、更高效、更轻便,消耗内存相比较 线程 更小。

使用goroutine的方法是:在函数调用前使用关键字go,创建1个并发任务单元,也就创建了1个并发任务。

什么时候需要使用goroutine?

1、业务逻辑需要并发

2、性能优化需要并发


有一个情况,用户1和用户2要使用喇叭发广播,那么用户1先来,用户2后来,来的时候用户1正在说话,那么这个时候用户1和用户2对喇叭就有了一个矛盾。

代码如下:

 package main

 import  (
   "fmt"
   "time"
)

func Speaker(str1 string) {
   for _, s := range str1 {
      c := fmt.Sprintf("%c", s)
      fmt.Print(c)
      time.Sleep(time.Second * 1)
   }
   fmt.Println()
}
func User1() {
   Speaker("今天星期一")
}
func User2() {
   Speaker("天气挺好的")
}

func main() {
   go User1()
   go User2()
   for {
   }
}
  

执行结果

发现执行结果并不是先执行user1,再执行user2。

这就是存在资源竞争的情况了。

那么怎么解决这个问题呢?

可以考虑使用通道解决。

1、首先声明1个通道

 var ch = make(chan string)  

2、在user1执行结束后,向通道中写入任意字符

 ch <- "我已经说完了"  

3、在user2执行前,获取通道字符,如果没有,那就阻塞,等待,如果获取到了就执行以下步骤

 <-ch  

代码如下:

 package main

import (
   "fmt"
   "time"
)

var ch = make(chan string)

func Speaker(str1 string) {
   for _, s := range str1 {
      c := fmt.Sprintf("%c", s)
      fmt.Print(c)
      time.Sleep(time.Second * 1)
   }
   fmt.Println()
}
func User1() {
   Speaker("今天星期一")
   ch <- "我已经说完了"
}
func User2() {
   <-ch
   Speaker("天气挺好的")

}

func main() {
   go User1()
   go User2()
   for {
   }
}
  

执行结果

相关文章