1、未初始化的channel读,阻塞

package main

import (
"fmt"
"time"
) func main() {
var ch chan int
go check(ch) fmt.Println("main runtime end")
time.Sleep(time.Second * 1000)
} func check(ch chan int) {
select {
case i := <-ch:
fmt.Println("read ch data=", i)
}
fmt.Println("check runtime exit")
}

2、未初始化的channel写,阻塞

package main

import (
"fmt"
"time"
) func main() {
go func() {
for {
time.Sleep(time.Second * 1)
}
}()
var ch chan int
go check(ch)
time.Sleep(time.Second * 1)
fmt.Println("xxxxxxx")
<-ch
fmt.Println("main runtime end")
time.Sleep(time.Second * 1000)
} func check(ch chan int) {
defer func() {
if r := recover(); r != nil {
fmt.Println("recover ", r)
}
}()
ch <- 1
fmt.Println("check runtime exit")
}

3、向已关闭的channel读,返回默认值和false

package main

import (
"fmt"
"time"
) func main() {
var ch chan int
ch = make(chan int)
go check(ch) fmt.Println("main runtime end")
close(ch)
time.Sleep(time.Second * 1000)
} func check(ch chan int) {
select {
case i, k := <-ch:
fmt.Println("read ch data=", i, " k=", k) //k=false i=0
}
fmt.Println("check runtime exit")
}

4、向已关闭的channel写,panic

package main

import (
"fmt"
"time"
) func main() {
var ch chan int
ch = make(chan int)
close(ch)
ch <- 1
fmt.Println("end")
time.Sleep(time.Second * 1000)
}

5、time.Timer Stop后,time.Timer.C将阻塞

package main

import (
"fmt"
"time"
) func main() {
tm := time.NewTimer(time.Second * 3)
go check(tm)
time.Sleep(time.Second * 1)
tm.Stop()
fmt.Println("main runtime end")
time.Sleep(time.Second * 1000)
} func check(tm *time.Timer) {
select {
case i, k := <-tm.C: //阻塞
fmt.Println("read ch data=", i, " k=", k)
}
fmt.Println("check runtime exit")
}

6、无缓冲与有缓冲channel的重要区别,无缓冲的channel在写时必须有读携程,否则会阻塞。如下例子,超时后向exit发数据会阻塞,因为只有一个携程,此时没有其他携程对exit进行读。【踩了坑才理解深刻】

package main

import (
"fmt"
"time"
) func main() {
exit := make(chan int)
go check(exit)
time.Sleep(time.Second * 100)
} func check(exit chan int) {
tm := time.NewTimer(time.Second * 3)
select {
case <-exit:
fmt.Println("exit")
case <-tm.C:
fmt.Println("time out")
exit <- 1
fmt.Println("exit <- 1 ok")
}
fmt.Println("check runtime exit")
}

例子2:

package main

import (
"fmt"
"time"
) func main() {
go func() {
for {
time.Sleep(time.Second * 1)
} }()
exit := make(chan int, 1)
exit <- 1
fmt.Println("end")
}

这里会直接END,如果exit:=make(chan int),会阻塞在exit<-1

最新文章

  1. Ionic2学习笔记(4):*号
  2. Guava学习笔记:EventBus
  3. Codeforce 287 div2 C题
  4. 在Dynamics CRM 2015中通过3CX插件(以及3CX windows phone)拨出电话
  5. -WEBKIT-USER-SELECT:NONE导致输入框无法输入
  6. Java断言assert
  7. MySQL5.7.12新密码登录方式及密码策略
  8. EQueue 2.3.2
  9. 什么是JSON对象
  10. pyqt5 动画学习(一) 改变控件大小
  11. 使用Jenkins docker镜像运行Jenkins服务
  12. LoadRunner通过SiteScope监控MySQL的性能
  13. centos7搭建SVN+Apache+IF.svnadmin支持https实现web管理SVN
  14. iOS 限制输入字数
  15. AnswerOpenCV(0826-0901)一周佳作欣赏
  16. position sticky的兼容
  17. 8 -- 深入使用Spring -- 3...1 Resource实现类FileSystemResource
  18. VIM 的一些技巧
  19. 算法笔记_157:算法提高 c++_ch02_01(Java)
  20. vue组件scoped CSS及/deep/深度选择器

热门文章

  1. Python3+telnetlib实现telnet客户端
  2. Microsoft Windows远程桌面协议中间人攻击漏洞(CVE-2005-1794)漏洞解决方案(Windows server2003)
  3. 码云git使用三(本地代码合并)
  4. 【Java算法】输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数
  5. JavaBean理解
  6. NTT模板(无讲解)
  7. .net core 在扩展中使用接口实例之IServiceProvider
  8. vue-router-2-动态路由配置
  9. json解析写入mysql
  10. C++基础知识:构造与析构