美文网首页golang研究所
golang并发获取唯一对象地址操作.

golang并发获取唯一对象地址操作.

作者: 百里江山 | 来源:发表于2020-02-16 20:55 被阅读0次

    利用pointer, atomic原子操作.实现并发只获取一个操作对象.

    import (
        "fmt"
        "sync/atomic"
        "testing"
        "time"
        "unsafe"
    )
    //使用自旋获取对象. 保证只有一个对象.
    type EtcdClient struct {
        username string
        password string
        id int
    }
    func NewEtcdClient() *EtcdClient {
        return &EtcdClient{
            username:"etcd",
            password:"root!root",
            id: 100,
        }
    }
    var etcdClientPointer unsafe.Pointer
    
    func Client() *EtcdClient {
        for {
            p := (*EtcdClient)(atomic.LoadPointer(&etcdClientPointer)) //如果指针存在则直接返回
            if p != nil {
                return p
            }
            //不存在则创建
            c := NewEtcdClient()
            //使用比较并载入操作
            if !atomic.CompareAndSwapPointer(&etcdClientPointer, nil, unsafe.Pointer(&c)) {
                time.Sleep(time.Nanosecond * 10) //休10纳秒
                continue
            }
            return c
        }
    }
    

    测试用例
    获取得地址是一样的.

    func TestNewEtcdClient(t *testing.T) {
        for i := 0;i < 10; i ++ {
            go func(i int) {
                fmt.Printf("%d, %p\n",i, Client())
            }(i)
        }
        time.Sleep(time.Second)
    }
    

    结果

    0xc000062240 #这个地址与下面地址不一样, 这是因为这个地址是对象实际存储的地址
    0xc000006018 # 以下地址是Pointer指针存储空间的地址.
    0xc000006018
    0xc000006018
    0xc000006018
    0xc000006018
    0xc000006018
    0xc000006018
    0xc000006018
    0xc000006018
    

    相关文章

      网友评论

        本文标题:golang并发获取唯一对象地址操作.

        本文链接:https://www.haomeiwen.com/subject/vywmfhtx.html