無緩衝的與有緩衝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 plaincopy
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...