go1.9新版本 並發安全的map使用及內部實現

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。Golang 1.9版本還沒有發布,大概在8月中旬發布,於是我看了下新版本都有哪些新東西,看來看去,看到了並發安全的Map於是我就看了一下源碼,本篇文章將帶領大家,看看新版本中 的並發安全的Map到底是個什麼樣子

軟體包中 的新Map類型sync是具有儲存和刪除的並發映射。多個goroutines可以同時調用Map的方法是安全的。

在新版本中官方是這樣描述的:

The new Map type in the sync package is a concurrent map with amortized-constant-time loads, stores, and deletes. It is safe for multiple goroutines to call a Map's methods concurrently.

使用方法

1.9以前都是自己通過鎖來處理map 的並發安全的並封裝成新的struct暴露給外部使用的,一下代碼是1.9的代碼使用案例:

func main() {list := map[string]interface{}{"name":          "田馥甄","birthday":      "1983年3月30日","age":           34,"hobby":         []string{"聽音樂", "看電影", "電視", "和姐妹一起討論私人話題"},"constellation": "白羊座",}var m sync.Mapfor k, v := range list {m.Store(k, v)}var wg sc.WaitGroupwg.Add(2)go func() {m.Store("age", 22)m.LoadOrStore("tag", 8888)wg.Done()}()go func() {m.Delete("constellation")m.Store("age", 18)wg.Done()}()wg.Wait()m.Range(func(key, value interface{}) bool {fmt.Println(key, value)return true})}

暴露出來了Map結構是開箱即用的,也可以聲明這樣的0值

var m sync.Map

sync包中暴露出來的map方法有:

func (m *Map) Load(key interface{}) (interface{},bool)func (m *Map) Store(key, value interface{})func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool)func (m *Map) Delete(key interface{}) func (m *Map) Range(f func(key, value interface{}) bool)

內部實現

接下來分別分析一下上面暴露出來的方法的內部實現,先查看一下sync.Map結構(sync.Map結構中使用了atomic.Value作為並發安全的替代方法,因為在使用atomic.Value的時候 ,一旦Store被調用那麼atomic.Value 就不能被複製,複製後會出現一些競爭問題,所以在使用sync.Map 的時候,在初始化之後也是不要複製sync.Map):

type Map struct {mu sync.Mutexread atomic.Value dirty map[interface{}]*entrymisses int}



func (m *Map) Load(key interface{}) (value interface{}, ok bool) {    read, _ := m.read.Load().(readOnly)    e, ok := read.m[key]    if !ok && read.amended {      m.mu.Lock()      read, _ = m.read.Load().(readOnly)      e, ok = read.m[key]      if !ok && read.amended {        e, ok = m.dirty[key]        m.missLocked()      }      m.mu.Unlock()    }    if !ok {      return nil, false    }    return e.load()}


func (m *Map) Store(key, value interface{}) {    read, _ := m.read.Load().(readOnly)    if e, ok := read.m[key]; ok && e.tryStore(&value) {      return    }      m.mu.Lock()    read, _ = m.read.Load().(readOnly)    if e, ok := read.m[key]; ok {      if e.unexpungeLocked() {        m.dirty[key] = e      }      e.storeLocked(&value)    } else if e, ok := m.dirty[key]; ok {      e.storeLocked(&value)    } else {      if !read.amended {        m.dirtyLocked()        m.read.Store(readOnly{m: read.m, amended: true})      }      m.dirty[key] = newEntry(value)    }    m.mu.Unlock()  }





func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {    read, _ := m.read.Load().(readOnly)    if e, ok := read.m[key]; ok {      actual, loaded, ok := e.tryLoadOrStore(value)      if ok {        return actual, loaded      }    }      m.mu.Lock()    read, _ = m.read.Load().(readOnly)    if e, ok := read.m[key]; ok {      if e.unexpungeLocked() {        m.dirty[key] = e      }      actual, loaded, _ = e.tryLoadOrStore(value)    } else if e, ok := m.dirty[key]; ok {      actual, loaded, _ = e.tryLoadOrStore(value)      m.missLocked()    } else {      if !read.amended {        m.dirtyLocked()        m.read.Store(readOnly{m: read.m, amended: true})      }      m.dirty[key] = newEntry(value)      actual, loaded = value, false    }    m.mu.Unlock()      return actual, loaded  }



func (m *Map) Delete(key interface{}) {    read, _ := m.read.Load().(readOnly)    e, ok := read.m[key]    if !ok && read.amended {      m.mu.Lock()      read, _ = m.read.Load().(readOnly)      e, ok = read.m[key]      if !ok && read.amended {        delete(m.dirty, key)      }      m.mu.Unlock()    }    if ok {      e.delete()    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.