学习了go的基本的并发变成模式,思路就是一个用通信来共享数据,而并不是像java一样共享内存来通讯。go采用了用channel来传递消息,每一个协程持有一个信道,当信道可用时便可以读写数据,各信道间的处理数据互不影响。回想一下java中的并发编程,通常我们是因为操作一个数据而采用多线程并发访问,比较明显的是更新cache中的key对应的value.
让我更是欢喜的时在golang中提供了sync.Once这个神器,从此做系统级的开关不再苦恼,天然的保证了就算多个协程并发的情况下也只有一个协程执行once.Do(func()),其他的协程阻塞。你再想想java里面完成一个系统级初始化,做到并发安全且一次,你要搞一个boolean、再搞把锁,再写逻辑,神啊想想头都大了。
下面是我的小尝试,你可以试试
package main import ( "fmt" "sync" "time" ) var counter int = 0 func main() { chls := make([]chan int, 10) for i := 0; i < 10; i++ { chls[i] = make(chan int) go addCounter(chls[i]) } for _, val := range chls { counter += <-val } fmt.Println("---结果是:", counter) //设置一个超时的chan,没有阻塞读超时,写超时,可由程序创建chan来判定是否有超时写入 timeout := make(chan bool, 1) subChn := chls[:2] for i := 0; i < 2; i++ { go timeoutAdd(i, subChn[i], timeout) } countDonw := 2 for { select { case <-subChn[0]: fmt.Println("not time out ") countDonw-- case <-timeout: fmt.Println("time out ") countDonw-- } if countDonw <= 0 { break } } //关闭channel for idx, ch := range chls { close(ch) _, ok := <-ch if !ok { fmt.Println("close channel ", idx) } } // //单向读channel // onedirchl := make(<-chan int) // //我来试试写操作,会有什么现象呢 // //go 会报invalid operation: onedirchl <- 1 (send to receive-only type <-chan int) // onedirchl <- close(onedirchl) //全局唯一性操作,大爱啊,想想java在做系统初始化只需要执行一次并且是多线程并发情况下的代码怎么写? //Lock ?全局boolean的开关,我的神啊,复杂 var once sync.Once completeChan := []chan bool{make(chan bool, 1), make(chan bool, 1)} //注意啊这里一定要传入指针,不然会是once的一个副本 go initConifg(&once, func() { fmt.Println("我是第一个初始化的channel!") completeChan[0] <- true }) go initConifg(&once, func() { fmt.Println("我是第二个完成初始化的channel!") completeChan[1] <- true }) for _, ch := range completeChan { <-ch close(ch) } } func initConifg(once *sync.Once, handler func()) { once.Do(func() { time.Sleep(5e9) fmt.Println("我这是初始化!,我等待了5S完成") }) handler() } func timeoutAdd(index int, chl chan int, timeout chan bool) { if index%2 != 0 { time.Sleep(5e9) fmt.Println("模拟超时了") timeout <- true } else { fmt.Println("正常输出..") chl <- 1 } } func addCounter(chl chan int) { chl <- 1 fmt.Println("countting") }
http://blackbeans.iteye.com/blog/1730314
相关推荐
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
半成品A Go game written in golang(Semi-finished).zip Java语言写的围棋小游戏。半成品A Go game written in golang(Semi-finished).zip Java语言写的围棋小游戏。半成品A Go game written in golang(Semi-...
开源项目-SaturnsVoid-GoLANG-Google-Chrome-Password-Recovery.zip,GoLANG-Google-Chrome-Password-Recovery
官方离线安装包,测试可用。使用rpm -ivh [rpm完整包名] 进行安装
The-Golang-Standard-Library-by-Example-master.zip
golang-stats-api-handler, Golang cpu,内存,gc等信息api处理程序 golang-stats-api-handlerGolang cpu,内存,gc等信息api处理程序。 安装go get github.com/fukata/golang-stats-api-handler示
go1.8.3-golang-linux-mips-openwrt-lede,go语言1.8.3在mips芯片的openwrt路由器上运行
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
golang-github-pmezard-go-difflib-unit-test-devel-0-0.9.git792786c.1.el7.x86_64 官方离线安装包,亲测可用
离线安装包,亲测可用
开源项目-NanXiao-golang-101-hacks.zip,Golang 101黑客
采用3D WebGL技术实现可视化预览。该工具旨在让开发者更好的了解Go并发。
好书不需介绍,急需者自知价值
golang-linux-arm64 SDK
golang标准库每次只支持加密16个字节(即128bit)长度的密钥,拿到二级密钥明文和IV向量后,无法解密openssl aes-256-cbc密文。
golang-ddp-server-源码.rar
golang-hex-dumper-源码.rar
开源项目-dkondratovych-golang-ua-meetup.zip,Presentation about Context in Go 1.7. Review, examples, thoughts.
开源项目-alaska-golang-ref-sheet.zip,alaska/golang-ref-sheet: A golang quick reference sheet. Your one stop concurrency shop!
秒杀项目实战 |Golang - Redis - RocketMQ-seckill