go channel 有快取和無快取的區別

2021-09-26 14:58:41 字數 3245 閱讀 1957

無緩衝的與有緩衝channel有著重大差別,那就是乙個是同步的 乙個是非同步的。

比如c1:=make(chan int)         無緩衝

c2:=make(chan int,1)      有緩衝

c1<-1                            

無緩衝: 不僅僅是向 c1 通道放 1,而是一直要等有別的攜程 <-c1 接手了這個引數,那麼c1<-1才會繼續下去,要不然就一直阻塞著。

有緩衝: c2<-1 則不會阻塞,因為緩衝大小是1(其實是緩衝大小為0),只有當放第二個值的時候,第乙個還沒被人拿走,這時候才會阻塞。

我對以上做一些解釋,首先確實得承認channel有快取與無快取確實差別巨大,快取為1和不設定快取輸出有差別。但是上面有快取的解釋是合理的,無快取的我保留一下意見,用用**例項來做下分析。

首先看示例1:

[plain] view plain

copy

package main  

import (  

"fmt"  

)  func main()  else   

//          fmt.println("goforend", i)  

}  }()  

for j := 1; j <= 3; j++   

close(jobs)  

fmt.println("sent all jobs")  

<-done  

}  

其輸出是:

[plain] view plain

copy

sent job 1  

received job 1  

sent job 2  

received job 2  

sent job 3  

sent all jobs  

received job 3  

received all jobs  

這是有快取的情況,輸出跟大家所預想的是一樣的,每次遇到

[plain] view plain

copy

jobs <- j  

程式會繼續向下執行,直到程式迴圈到下次 jobs <- j,因為jobs的開闢的快取已滿,故程式轉而執行goroutine部分,在goroutine中,當程式執行至

[plain] view plain

copy

j, more := <-jobs  

取出channel中的值,等到goroutine中遇到阻塞,回到外部main()函式繼續執行

然後分析看示例2:

[plain] view plain

copy

jobs := make(chan int, 1)  

修改為[plain] view plain

copy

jobs := make(chan int)  

並將**中的注釋部分全部還原執行。

其輸出是:

[plain] view plain

copy

outfor 1  

gostart  

goforstart 1  

received job 1  

goforend 1  

goforstart 2  

sent job 1  

outfor 2  

sent job 2  

outfor 3  

received job 2  

goforend 2  

goforstart 3  

received job 3  

goforend 3  

goforstart 4  

sent job 3  

sent all jobs  

received all jobs  

我們分析:

當for迴圈執行至第一次 jobs <- j ,程式直接進入goroutine,由輸出的「 gostart」 緊跟 「outfor 1」 得到驗證。然後程式執行至在goroutine中for的第二次迴圈

[plain] view plain

copy

j, more := <-jobs  

處阻塞,回到外部main()的for迴圈。

但外部main的for迴圈執行第二圈時,並未在 jobs <- j  後進入goroutine,而是繼續執行,由

[plain] view plain

copy

sent job 2  

outfor 3  

緊跟[plain] view plain

copy

outfor 2  

得到驗證。

而外部for進入第三次迴圈時阻塞,因為jobs中得值還未取出,故而轉入goroutine繼續執行。

問題出在

[plain] view plain

copy

jobs <- j  

是繼續執行還是阻塞去在其他goroutine中傳遞值,按照本文開頭索引的帖子所指出,應該jobs 通道放j,需要有攜程接手這個引數,才可繼續執行,但上面得分析看到情況並非如此。

示例3:

[plain] view plain

copy

package main  

import (  

"fmt"  

)  func main()   

}  }()  

for j := 0; j < 5; j++   

close(jobs)  

fmt.println("finish.")  

}  其輸出為:

[plain] view plain

copy

goroutin start  

get  0  

sent job  0  

sent job  1  

get  1  

get  2  

sent job  2  

sent job  3  

get  3  

get  4  

sent job  4  

finish.  

當遇到向channel寫入值,是否往下執行是交替的,也就是說是隨機的。

本文示例環境是go 1.4,本文所做的解釋也是因為攜程都是利用同一cpu在不同時間片上執行所做的輸出分析。

goroutine利用阻塞同步攜程之間的資料是非常重要的思想,但大家程式設計的時候要特別小心。

mybatis查詢快取之一級快取和二級快取詳細解析

一級快取是mybatis預設就幫我們開啟的,我們不需要多做配置,但是我們得知道其中原理,否則我們也不知道怎麼使用,也不知道我們到底有沒有一級快取。上面第二部分說過一級快取的作用域是同乙個sqlsession,sqlsession的作用就是建立和資料庫的會話,我們對資料庫表的增刪改查都是通過sqlse...

對比有引數和無引數

有引數 小括號當中有內容,當乙個方法需要一些資料條件,才能完成任務的時候們就是有引數,如 兩個數字相加,必須知道兩個數字各自多少,才能相加。裡面有方法,但沒有引數,需要外加資料 無引數 小括號當中留空,乙個方法不需要任何資料條件,自己就能獨立完成任務,就是無引數。裡面有方法,也有資料 但需要你呼叫 ...

有類查詢和無類查詢

有類路由查詢 路由器首先匹配主網路號,如果主網路號存在,就繼續匹配子網號,且不考慮預設路由,如果子網無法匹配,丟棄資料報 如果主網路號不存在,使用預設路由 預設路由存在前提 無類路由查詢 不區分a,b,c,d類網路型別,按照位元逐位查詢,如果沒有找到最具體的匹配,就使用預設路由。有類路由查詢例子 r...