Go 语言基础——协程(goroutine)&共享内存线程安全
协程(goroutine)是更轻量级的线程
比Java中的线程效率更高
协程语法
go func() {
//...
}()一旦主goroutine中的代码执行完毕,当前的Go程序就会结束运行,无论其他的 goroutine是否已经在运行了。
让主goroutine等待其它 goroutine:
for i := 0; i < 10; i++ {
go func() {
fmt.Println(i)
}()
}
time.Sleep(time.Millisecond * 1000)
//goroutine 完成的时间很可能小于设置的等待时间,那么这就会造成多余的等待时间怎么才能让goroutine执行完后立刻执行下一个goroutine呢?
go语言提供的WaitGroup可以实现这样的功能.
代码改造:
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)//每启动一个协程增加一个等待
go func() {
fmt.Println(i)
wg.Done()//告诉协成等待的事务已经完成
}()
}
/*
这样我们就不用设置等待时间了,但是执行输出的内容是这样的: 3 7 4 8 8 8 9 10 10 10, 很显然这种方式不能保证goroutine拿到唯一整数
*/如何保证每个线程拿到的数是惟一的?
代码改造:
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)//每启动一个协程增加一个等待
go func(j int) {//把j只是个形参可以任意命名
fmt.Println(j)
wg.Done()//告诉协成等待的事务已经完成
}(i)//把实参i传递给形参j
}
//执行结果:0 2 1 6 3 4 5 8 7 9我们把i值传递给j,i的变化不会影响j的值,所以输出的结果是唯一的
共享内存线程安全
func TestCounter(t *testing.T) {
counter := 0
for i := 0; i < 5000; i++ {
go func() {
counter++
}()
}
time.Sleep(1 * time.Second)
t.Logf("counter = %d", counter)
}
//执行结果: 4760 出现了线程安全的问题和大多数语言一样go也支持加锁保证线程的安全:
func TestCounterWaitGroup(t *testing.T) {
var mut sync.Mutex//创建锁对象
var wg sync.WaitGroup
counter := 0
for i := 0; i < 5000; i++ {
wg.Add(1)//每启动一个协程增加一个等待
go func() {
defer func() {
mut.Unlock()//释放锁
}()
mut.Lock()//开启锁
counter++
wg.Done()//告诉协成等待的事务已经完成
}()
}
wg.Wait()//等待协程
t.Logf("counter = %d", counter)
}码字不易如果对你有帮助请给个关注
爱技术爱生活 QQ群: 894109590
相关推荐
zhuyonge 2020-08-01
fraternityjava 2020-06-26
三动 2020-06-21
Hy 2020-11-13
xrslt 2020-11-06
yutian0 2020-10-26
杨树 2020-09-21
zhuyonge 2020-07-26
xiaoemo0 2020-07-18
luohui 2020-06-26
dxyadc 2020-06-26
luohui 2020-06-21
fengyun 2020-06-14
fraternityjava 2020-06-14
waitui00 2020-06-14
fraternityjava 2020-06-10
shayuchaor 2020-06-07