go学习 sync.Map

设想这样的场景,有很多人订阅某种数据。当用户订阅成功后我们需要按功能批量推送给用户。假设用户有3人:greece,lodon,egypt订阅了某个功能的数据,一旦这个功能的数据有新数据到达,我们需要一次性将这些数据推送给订阅的用户

我们想到最简单的方法就是定义一个map,key用来存放用户指针, value随便存放一个数,假设bool类型

先建一个用户类型:

type User struct {
	connect int64
	Name    string
}

然后再建一个根据用户名创建用户的函数:

func MakeUser(name string) *User {
	u := new(User)
	u.Name = "greece"
	return u
}

现在我们开始创始化一个用户集:这个用户集最后返回一个sync.Map

func InitUsers() sync.Map {
	var scene sync.Map
	u1 := MakeUser("greece")
	u2 := MakeUser("london")
	u3 := MakeUser("egypt")

	scene.Store(u1, true)
	scene.Store(u2, true)
	scene.Store(u3, true)
	return scene
}

顺带说一下,如果需要删除:

scene.Delete(u1)

可以线程安全地完成删除工作。

由于订阅和推送在不同的线程中,我们利用了go自带的多线程的map进行。这里最主要的是要实现把map中的key一次性取出,然后推送出去的功能。

sync.Map中遍历需要使用匿名函数

scene.Range(func(k, v interface{}) bool {
   number, _ := k.(*User)
   fmt.Println(number.Name)
   return true
})

可以打印出每个用户的指针。

我们不能在回调中进行数据的发送,因此需要通过一个缓存,将指针放入此缓存中,供推送函数使用

	var users []*User
	scene.Range(func(k, v interface{}) bool {
		number, _ := k.(*User)
		users = append(users, number)
		return true
	})
	fmt.Println("从sync.Map中取出的元素...")
	for _, value := range users {
		fmt.Println(value.Name)
	}

当我们取出了map中的指针时,就可以一次性将分时数据推送给用户了。

有同学会说,我可能在别的线程中删除了指针,引发空指针的问题,这个不用担心,如果你在其它线程中先一步删除了某个指针,则遍历时不会得到对应的元素,若你在遍历后删除了某个指针,此时这个指针存在users数组中,不会空挂,根据go语言特性,只要有变量在使用,指针就不会被删除。

附全部代码:

// 测试 sync.map
package test

import (
	"fmt"
	"sync"
	"testing"
)

type User struct {
	connect int64
	Name    string
}

func MakeUser(name string) *User {
	u := new(User)
	u.Name = "greece"
	return u
}

func InitUsers() sync.Map {
	var scene sync.Map
	u1 := MakeUser("greece")
	u2 := MakeUser("london")
	u3 := MakeUser("egypt")

	scene.Store(u1, true)
	scene.Store(u2, true)
	scene.Store(u3, true)
	return scene
}

func TestSyncMap(t *testing.T) {

	scene := InitUsers()
	var users []*User
	scene.Range(func(k, v interface{}) bool {
		number, _ := k.(*User)
		users = append(users, number)
		return true
	})
	fmt.Println("从sync.Map中取出的元素...")
	for _, value := range users {
		fmt.Println(value.Name)
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

永远的麦田

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值