1. 实现一个线程安全的map
type RWMap struct {
Lock sync.RWMutex
DMap map[string]string
}
func (r *RWMap)Get(key string)string{
r.Lock.RLock()
defer r.Lock.RUnlock()
if v,ok := r.DMap[key]; ok {
return v
}
return ""
}
func (r *RWMap) Put(k,v string) {
r.Lock.Lock()
defer r.Lock.Unlock()
if r.DMap == nil {
r.DMap = make(map[string]string)
}
r.DMap[k] = v
}
2. 并发读写
package main
import (
"context"
"fmt"
"sync"
"time"
)
func main() {
c := make(chan int,10)
wg := sync.WaitGroup{}
ctx,cancel := context.WithCancel(context.Background())
// 专门用来关闭的协程
go func() {
time.Sleep(1*time.Second)
cancel()
// 某种条件下,关闭channel
close(c)
}()
// (写端)
for i:=0;i<10; i++ {
go func(ctx context.Context, id int) {
select {
case <- ctx.Done():
fmt.Println("done...")
case c <- id:
fmt.Println("写入数据: ",id)
default:
fmt.Println("....")
}
}(ctx,i)
}
// (读端)
for i:=0; i<100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// 。。。 处理channel 中的数据
for v := range c {
fmt.Println("读取数据: ",v)
}
}()
}
// 等待所有的读端完成
wg.Wait()
}
3. 多写多读
需要设置一个额外 channel 用来通知多个写入端和读取端。另外需要起一个额外的协程来通过关闭这个 channel 来广播通知:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wg := sync.WaitGroup{}
c := make(chan int,10)
done := make(chan bool)
// (写端)
for i:=0;i<10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
select {
case <- done:
fmt.Println("sender done...")
return
case c <- id:
fmt.Println("写入数据: ",id)
//default:
// fmt.Println("sender blocking...")
}
}(i)
}
// (读端)
for i:=0; i<10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// 。。。 处理channel 中的数据
for {
select {
case <-done:
fmt.Println("receiver done...")
return
case v:= <-c:
fmt.Println("receiver get :",v)
time.Sleep(time.Millisecond)
//default:
// fmt.Println("receiver blocking...")
}
}
//for v := range c {
// fmt.Println("读取数据: ",v)
//}
}()
}
time.Sleep(time.Second)
close(done)
// 等待所有的读端完成
wg.Wait()
}
4. 生产者消费者
package main
import (
"fmt"
"time"
)
func Product(ch chan<- int) {
for i:=0; i<10; i++ {
fmt.Println("Product: ",i)
ch <- i
}
close(ch)
}
func Consumer(ch <-chan int,done chan bool) {
for i:=0; i<10; i++ {
a := <- ch
fmt.Println("Consumer:",a)
}
done <- true
close(done)
}
func main() {
ch := make(chan int,10)
done := make(chan bool,1)
go Product(ch)
go Consumer(ch,done)
for {
select {
case _,ok := <-done:
if ok {
fmt.Println("执行完毕")
return
}
default:
time.Sleep(time.Second)
return
}
}
}