Fixes #198
This commit is contained in:
chai2010
2016-01-18 11:22:04 +08:00
parent 884ada9cd0
commit 9666211cd7
71 changed files with 107 additions and 105 deletions

View File

@@ -87,7 +87,7 @@ func Icon(name string) image.Image {
```
上面的代碼有兩個臨界區。goroutine首先會獲取一個寫鎖査詢map然後釋放鎖。如果條目被找到了(一般情況下)那麽會直接返迴。如果沒有找到那goroutine會獲取一個寫鎖。不釋放共享鎖的話也沒有任何辦法來將一個共享鎖陞級爲一個互斥鎖所以我們必重新檢査icons變量是否爲nil以防止在執行這一段代碼的時候icons變量已經被其它gorouine初始化過了。
上面的代碼有兩個臨界區。goroutine首先會獲取一個寫鎖査詢map然後釋放鎖。如果條目被找到了(一般情況下)那麽會直接返迴。如果沒有找到那goroutine會獲取一個寫鎖。不釋放共享鎖的話也沒有任何辦法來將一個共享鎖陞級爲一個互斥鎖所以我們必重新檢査icons變量是否爲nil以防止在執行這一段代碼的時候icons變量已經被其它gorouine初始化過了。
上面的模闆使我們的程序能夠更好的併發但是有一點太複雜且容易出錯。幸運的是sync包爲我們提供了一個專門的方案來解決這種一次性初始化的問題sync.Once。概念上來講一次性的初始化需要一個互斥量mutex和一個boolean變量來記録初始化是不是已經完成了互斥量用來保護boolean變量和客戶端數據結構。Do這個唯一的方法需要接收初始化函數作爲其參數。讓我們用sync.Once來簡化前面的Icon函數吧