一文帶你掌握Golang基礎(chǔ)之通道
前言
在Java中,多線程之間的通信方式有哪些?記得嗎?Java多線程間通信的解決方案有很多種,比如:synchronized。使用鎖來(lái)防止資源亂來(lái),一人一個(gè)按順序來(lái),要么使用JDK提供的原子對(duì)象,那些Atomic關(guān)鍵字開(kāi)頭的對(duì)象,比如:AtomicInteger,這樣可以在多個(gè)線程中讀寫(xiě)值的時(shí)候保證是安全的,還有很多其他的方式,在go中,就一種:通道
通道
go的通道我根據(jù)java的理解,它就是用來(lái)解決線程之間通信的東西,go里面的關(guān)鍵字叫channels
以下是搜索出來(lái)的解釋:
go語(yǔ)言提倡使用通信的方法代替共享內(nèi)存,當(dāng)一個(gè)資源需要在 goroutine 之間共享時(shí),通道在 goroutine 之間架起了一個(gè)管道,并提供了確保同步交換數(shù)據(jù)的機(jī)制。聲明通道時(shí),需要指定將要被共享的數(shù)據(jù)的類型。可以通過(guò)通道共享內(nèi)置類型、命名類型、結(jié)構(gòu)類型和引用類型的值或者指針。這里通信的方法就是使用通道(channel),如下圖所示:
圖:goroutine 與 channel 的通信
是不是和java的線程安全對(duì)象是類似?或者說(shuō)是隊(duì)列?總之你可以按照你自己經(jīng)驗(yàn)去理解。
如何創(chuàng)建通道
go提供了創(chuàng)建通道的語(yǔ)法:
通道變量名 := make(chan 數(shù)據(jù)類型)
比如,我們可以這樣寫(xiě):
// 創(chuàng)建一個(gè)int型的通道 ch1 := make(chan int)
還可以創(chuàng)建一個(gè)接口類型通道,比如:
ch2 := make(chan interface{})
還能創(chuàng)建一個(gè)結(jié)構(gòu)體的通道,比如:
// 創(chuàng)建一個(gè)User結(jié)構(gòu)體的通道,這個(gè)通道是個(gè)指針通道 ch3 := make(chan *User)
向通道發(fā)送數(shù)據(jù)
go向通道發(fā)送數(shù)據(jù)語(yǔ)法非常簡(jiǎn)單:
通道變量名 <- 值
我們向上面三個(gè)通道名發(fā)送數(shù)據(jù),可以寫(xiě)成:
// 1. 給ch1通道傳值0 ch1 <- 0 // 2. 給ch2通道傳字符串,實(shí)際可以穿任意對(duì)象,因?yàn)榍懊媛暶髁耸莍nterface對(duì)象 ch2 <- "hello, mars醬" // 創(chuàng)建一個(gè)userInfo結(jié)構(gòu)體并初始化值 userInfo := User{ 1, "mars醬", } // 3. 發(fā)送一個(gè)結(jié)構(gòu)體到通道ch3中 ch3 <- &userInfo
以上代碼是無(wú)法運(yùn)行的,因?yàn)間o的通道有個(gè)規(guī)矩,發(fā)送和接收必須成對(duì)出現(xiàn),不信邪的可以驗(yàn)證一下。
從通道接收數(shù)據(jù)
go從通道中接收數(shù)據(jù)的語(yǔ)法也簡(jiǎn)單:
data := <- ch1
這個(gè)語(yǔ)句是個(gè)阻塞語(yǔ)句,只有當(dāng)data接收到了值,才會(huì)執(zhí)行后續(xù)的,非阻塞的這樣寫(xiě):
data, ok := <- ch1
data
:接收的數(shù)據(jù),如果沒(méi)有接收到,data為0。data為0取決于之前make通道的時(shí)候,ch1是個(gè)int型通道,如果是其他類型,這個(gè)data也應(yīng)該是其他類型對(duì)象;
ok
:boolean類型的值,表示是否接收到數(shù)據(jù)
還有個(gè)奇葩的寫(xiě)法:
<- ch1
這樣寫(xiě)就表示通道里有啥都與我無(wú)關(guān),忽略掉了。
通道的例子
一個(gè)倒數(shù)的例子,通過(guò)通道去實(shí)現(xiàn)一下:
// author: mars醬 func Test_chanTest(t *testing.T) { // 1. 創(chuàng)建一個(gè)通道 ch1 := make(chan int) // 2. 啟動(dòng)goroutine并發(fā) go func() { // 從5 到 0 for i := 5; i >= 0; i-- { // 3. 發(fā)送給通道 ch1 <- i // 發(fā)完后等1秒 time.Sleep(time.Second) } }() // 4. 循環(huán)接收通道數(shù)據(jù) for data := range ch1 { fmt.Println(data) if data == 0 { break } } }
運(yùn)行的結(jié)果:
發(fā)射火箭的倒數(shù)計(jì)時(shí)就是這樣吧~
以上就是一文帶你掌握Golang基礎(chǔ)之通道的詳細(xì)內(nèi)容,更多關(guān)于Golang通道的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- golang關(guān)閉chan通道的方法示例
- Go語(yǔ)言帶緩沖的通道的使用
- Go語(yǔ)言無(wú)緩沖的通道的使用
- 一文教你Golang如何正確關(guān)閉通道
- 詳解Golang中的通道機(jī)制與應(yīng)用
- Go語(yǔ)言?Channel通道詳解
- golang使用通道時(shí)需要注意的一些問(wèn)題
- Go語(yǔ)言通道之無(wú)緩沖通道與緩沖通道詳解
- 超實(shí)用的Golang通道指南之輕松實(shí)現(xiàn)并發(fā)編程
- Go語(yǔ)言單向通道的實(shí)現(xiàn)
- 淺談golang通道類型
- Golang通道的無(wú)阻塞讀寫(xiě)的方法示例
- Golang通道阻塞情況與通道無(wú)阻塞實(shí)現(xiàn)小結(jié)
相關(guān)文章
Go語(yǔ)言同步與異步執(zhí)行多個(gè)任務(wù)封裝詳解(Runner和RunnerAsync)
這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言同步與異步執(zhí)行多個(gè)任務(wù)封裝(Runner和RunnerAsync)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01Go語(yǔ)言實(shí)現(xiàn)常見(jiàn)限流算法的示例代碼
計(jì)數(shù)器、滑動(dòng)窗口、漏斗算法、令牌桶算法是我們常見(jiàn)的幾個(gè)限流算法,本文將依次用Go語(yǔ)言實(shí)現(xiàn)這幾個(gè)限流算法,感興趣的可以了解一下2023-05-05優(yōu)雅使用GoFrame共享變量Context示例詳解
這篇文章主要為大家介紹了優(yōu)雅使用GoFrame共享變量Context示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06go?mod?tidy報(bào)錯(cuò):zip:?not?a?valid?zip?file解決辦法
這篇文章主要給大家介紹了關(guān)于go?mod?tidy報(bào)錯(cuò):zip:?not?a?valid?zip?file的解決辦法,go mod是進(jìn)行代碼管理,這錯(cuò)誤是因?yàn)楸镜胤种Ш瓦h(yuǎn)程分支沖突,本文通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01golang?gorm開(kāi)發(fā)架構(gòu)及寫(xiě)插件示例
這篇文章主要為大家介紹了golang?gorm開(kāi)發(fā)架構(gòu)及寫(xiě)插件的詳細(xì)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04