天天看點

并發程式設計2-安全的釋出對象

前文隻是介紹了volitale關鍵字能夠關閉重排序,緩存寄存器等優化來防止可見性發生問題。

但是并發程式設計更多的是對釋出(放到可以供其他線程通路的區域,比如static 集合等)的對象進行多線程處理,這裡讨論下如何能夠安全的釋出這些對象。

通常有如下的手段:

 局部變量,也就是方法内的變量,因為線程私有棧,是以這個變量也是私有的,不會存在并發問題。 當然這個不是解決線程共享對象的,實際上我們寫的代碼中大多數的對象都是這樣使用的,是以沒有故意去注意并發仍然運作起來沒有問題。

使用threadlocal來把一個對象變成線程内共享。 也不是解決線程間共享的,其很适用于儲存線程内很多地方都會用到的大對象。

原理上比較簡單。 在虛拟機上維護了一個map,可以根據目前線程id得到另外一個map,然後根據目前threadlocal執行個體來得到hold的對象。

這種對象内部使用了鎖或者其他的機制,保證了每個方法都是安全的。  jvm在性能和安全上的考慮對很多類都提供了兩個版本的實作,安全的和不安全的。比如

atomicinteger 和integer

stringbuffer 和stringbuilder

vector和arraylist

hashtable和hashmap等等。

将會列印 1327 2000.

可見不安全的計數器是有問題的。

atomicinteger并不是通過鎖的機制來解決并發問題的,而是使用如下的代碼:

這樣可以獲得更好的性能, 之後還會讨論

stringbuffer和stringbuilder

将會列印2000和17836

這個是因為stringbuilder是線程不安全的,是以在并發寫入的時候,内部狀态出現了錯誤。   但是它相對快一點,單線程的時候可以使用。

集合的并發後面再說

繼續閱讀