mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-10-26 16:22:13 +00:00
@@ -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函數吧:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user