栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Go-条件变量的那些事

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Go-条件变量的那些事

Wait():

    把当前的 goroutine 加入当前条件变量的通知队列.解锁当前条件变量基于的互斥锁. 所以 wait 前必须加锁.当前 goroutine 阻塞在 wait()通知到来并唤醒了当前 goroutine 后
      解锁当前条件变量基于的互斥锁执行后面的代码

Signal()Broadcast

上代码, 自己品:

package main

import (
	"fmt"
	"sync"
	"time"
)

type MailBox struct {
	count    uint8
	locker   sync.RWMutex
	sendCond *sync.Cond
	recvCond *sync.Cond
}

func (self *MailBox) Init() {
	self.sendCond = sync.NewCond(&self.locker)
	self.recvCond = sync.NewCond(self.locker.RLocker())
}

func (self *MailBox) Send() {
	self.locker.Lock()
	defer self.locker.Unlock()
	for self.count == 1 {
		fmt.Println("Send wait...")
		self.sendCond.Wait()
	}
	fmt.Println("Send")
	self.count = 1
	self.recvCond.Signal()
}

func (self *MailBox) Recv() {
	self.locker.RLock()
	defer self.locker.RUnlock()
	for self.count == 0 {
		fmt.Println("Recv wait...")
		self.recvCond.Wait()
	}
	fmt.Println("Recv")
	self.count = 0
	self.sendCond.Signal()
}

func main() {
	var mailBox MailBox
	mailBox.Init()

	go func() {
		for i := 0; i < 5; i++ {
			mailBox.Send()
		}
	}()

	go func() {
		for i := 0; i < 5; i++ {
			mailBox.Recv()
		}
	}()

	time.Sleep(time.Second * 2)
}

package main

import (
	"fmt"
	"sync"
	"time"
)

type MailBox struct {
	count    uint8
	locker   sync.RWMutex
	sendCond *sync.Cond
	recvCond *sync.Cond
}

func (self *MailBox) Init() {
	self.sendCond = sync.NewCond(&self.locker)
	self.recvCond = sync.NewCond(self.locker.RLocker())
}

func (self *MailBox) Send(i int) {
	fmt.Println(i)
	self.locker.Lock()
	fmt.Println(i, "lock")
	defer self.locker.Unlock()
	for self.count == 1 {
		fmt.Println(i, " Send wait...")
		self.sendCond.Wait()
	}
	fmt.Println(i, " Send")
	self.count = 1
	self.recvCond.Signal()
}

func (self *MailBox) Recv() {
	self.locker.RLock()
	defer self.locker.RUnlock()
	for self.count == 0 {
		fmt.Println("Recv wait...")
		self.recvCond.Wait()
	}
	fmt.Println("Recv")
	self.count = 0
	self.sendCond.Signal()
}

func main() {
	var mailBox MailBox
	mailBox.Init()

	go func() {
		for i := 0; i < 5; i++ {
			mailBox.Send(i) // Send 里面的 for 循环会阻塞
		}
	}()

	time.Sleep(time.Second * 2)
}



package main

import (
	"fmt"
	"sync"
	"time"
)

type MailBox struct {
	count    uint8
	locker   sync.RWMutex
	sendCond *sync.Cond
	recvCond *sync.Cond
}

func (self *MailBox) Init() {
	self.sendCond = sync.NewCond(&self.locker)
	self.recvCond = sync.NewCond(self.locker.RLocker())
}

func (self *MailBox) Send(i int) {
	fmt.Println(i)
	self.locker.Lock()
	fmt.Println(i, "lock")
	defer self.locker.Unlock()
	for self.count == 1 {
		fmt.Println(i, " Send wait...")
		self.sendCond.Wait()
	}
	fmt.Println(i, " Send")
	self.count = 1
	self.recvCond.Signal()
}

func (self *MailBox) Recv() {
	self.locker.RLock()
	defer self.locker.RUnlock()
	for self.count == 0 {
		fmt.Println("Recv wait...")
		self.recvCond.Wait()
	}
	fmt.Println("Recv")
	self.count = 0
	self.sendCond.Signal()
}

func main() {
	var mailBox MailBox
	mailBox.Init()

	go func() {
		for i := 0; i < 5; i++ {
			go func(i int) {
				mailBox.Send(i) // wait 调用后, 其他的Send就可以获得锁了
			}(i)
		}
	}()

	time.Sleep(time.Second * 2)
}



package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var locker sync.Mutex

	var cond *sync.Cond = sync.NewCond(&locker)

	go func() {
		locker.Lock()
		defer locker.Unlock()
		time.Sleep(time.Second * 1)
		fmt.Println("1: wait...")
		cond.Wait()
	}()

	go func() {
		//cond2 := cond // 可以在 cond 使用前拷贝
		cond2 := *cond // 可以在 cond 使用前拷贝
		locker.Lock()
		defer locker.Unlock()
		time.Sleep(time.Second * 2)
		fmt.Println("2: wait...")
		cond2.Wait()
	}()

	time.Sleep(time.Second * 5)
}

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var locker sync.Mutex

	var cond *sync.Cond = sync.NewCond(&locker)

	go func() {
		locker.Lock()
		defer locker.Unlock()
		time.Sleep(time.Second * 1)
		fmt.Println("1: wait...")
		cond.Wait()
	}()

	go func() {
		locker.Lock()
		defer locker.Unlock()
		time.Sleep(time.Second * 2)
		cond2 := cond // 在 cond 使用后拷贝指针的副本, 可以使用
		fmt.Println("2: wait...")
		cond2.Wait()
	}()

	time.Sleep(time.Second * 5)
}

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var locker sync.Mutex

	var cond *sync.Cond = sync.NewCond(&locker)

	go func() {
		locker.Lock()
		defer locker.Unlock()
		time.Sleep(time.Second * 1)
		fmt.Println("1: wait...")
		cond.Wait()
	}()

	go func() {
		locker.Lock()
		defer locker.Unlock()
		time.Sleep(time.Second * 2)
		cond2 := *cond // 在 cond 使用后拷贝值的副本, 不可以使用
		fmt.Println("2: wait...")
		cond2.Wait() // panic: sync.Cond is copied
	}()

	time.Sleep(time.Second * 5)
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/732421.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号