并发编程实战-第二章学习
“共享”意味著變量可以由多個(gè)線程同時(shí)訪問(wèn),而“可變”則意味著變量的值再其聲明周期內(nèi)可以發(fā)生變化。
如果當(dāng)多個(gè)線程訪問(wèn)同一個(gè)可變的狀態(tài)變量時(shí)沒(méi)有使用合適的同步,那么程序就會(huì)出現(xiàn)錯(cuò)誤,有三種方式可以修復(fù)這個(gè)問(wèn)題:
- 不在線程之間共享該狀態(tài)變量(有點(diǎn)扯,既然我要共享一個(gè)狀態(tài)變量,怎么可能不共享,只能說(shuō)不共享肯定不會(huì)涉及狀態(tài)的同步)
- 將狀態(tài)變量修改為不可變的變量。
- 在訪問(wèn)狀態(tài)變量時(shí)使用同步
什么是線程安全性
線程安全性的核心是正確性,即當(dāng)多個(gè)線程訪問(wèn)某個(gè)類時(shí),這個(gè)類使用都能變現(xiàn)出正確的行為,那么這個(gè)類就是線程安全的。
在線程安全性一章中給出的定義:
當(dāng)多個(gè)線程訪問(wèn)某個(gè)類時(shí),不管運(yùn)行環(huán)境采用何種調(diào)度凡是或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個(gè)類都能變現(xiàn)出正確的行為,那么就稱這個(gè)類時(shí)線程安全的無(wú)狀態(tài)對(duì)象一定是線程安全的,無(wú)狀態(tài)即不包括任何域、也不包括任何對(duì)其他類中的域的引用。
?
原子性
原子操作是指,對(duì)于訪問(wèn)同一個(gè)狀態(tài)的所有操作(包括該操作本身)來(lái)說(shuō),這個(gè)操作是一個(gè)原子的操作。(個(gè)人理解:所謂的原子,即最小單位,不可再分割,對(duì)于操作來(lái)說(shuō),及時(shí)是復(fù)合操作,同樣通過(guò)加鎖等其他方式將其捆綁在一起完成)
該節(jié)提出了產(chǎn)生數(shù)據(jù)不一致的問(wèn)題,從而引出了,“先檢查后執(zhí)行”的操作,即通過(guò)一個(gè)可能失效的觀察結(jié)果來(lái)決定下一步的動(dòng)作。通過(guò)舉例了兩個(gè)朋友相約咖啡廳的故事進(jìn)行了描述,通俗易懂,其中我個(gè)人認(rèn)為比較重要的一句----“當(dāng)你邁出前門時(shí),你在星巴克A的觀察結(jié)果將變得無(wú)效,因?yàn)樗赡芤呀?jīng)從后門進(jìn)入了星巴克,只是你不知道而已”。、
通過(guò)long的couut操作說(shuō)明了符合操作,++count,涉及的操作為讀取-修改-寫入三部分操作,通過(guò)使用java.util.concurrent.atmoic包中的原子變量類AtomicLong來(lái)代替long類型來(lái)解決該問(wèn)題是其成為一個(gè)線程安全的操作。
在實(shí)際情況中,應(yīng)盡可能地使用現(xiàn)有的線程安全對(duì)象(例如AtomicLong)來(lái)管理類的狀態(tài),與非線程安全的對(duì)象相比,判斷線程安全對(duì)象的可能狀態(tài)及其狀態(tài)轉(zhuǎn)換情況要更為容器,從而更容易維護(hù)和驗(yàn)證線程安全性
?加鎖機(jī)制
要保值狀態(tài)的一致性,就需要在單個(gè)原子操作中更新所有相關(guān)的狀態(tài)變量。
重入意味著獲取鎖的操作的粒度是線程,而不是調(diào)用。重入的一種實(shí)現(xiàn)方法是,為每個(gè)鎖關(guān)聯(lián)一個(gè)獲取計(jì)數(shù)值和一個(gè)所有者線程。
?一種常見(jiàn)的加鎖約定是,將所有的可變狀態(tài)都封裝在對(duì)象內(nèi)部,并通過(guò)對(duì)象的內(nèi)置鎖對(duì)所有訪問(wèn)可變的代碼路徑進(jìn)行同步,使得在該對(duì)象上不會(huì)發(fā)生并發(fā)訪問(wèn)。
需要注意的一點(diǎn)是即使是同步方法的符合操作,同樣會(huì)導(dǎo)致競(jìng)態(tài)條件問(wèn)題。如下代碼,雖然vector是的每個(gè)方法是原子方法,但是復(fù)合操作,同樣會(huì)導(dǎo)致出現(xiàn)數(shù)據(jù)不一致問(wèn)題。
1 if ( !vector.contains(element)) 2 vector.add(element)?
遺留問(wèn)題
1、原子性小節(jié)同樣提到了單例的實(shí)現(xiàn),該問(wèn)題需要統(tǒng)一整理所有單例的實(shí)現(xiàn)方法,記一個(gè)遺留問(wèn)題,下周解決
已經(jīng)復(fù)習(xí)了單例的相關(guān)知識(shí),見(jiàn):http://www.cnblogs.com/woniu4/p/8287484.html
?
轉(zhuǎn)載于:https://www.cnblogs.com/woniu4/p/8284244.html
總結(jié)
以上是生活随笔為你收集整理的并发编程实战-第二章学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Centos7 Zookeeper
- 下一篇: labview事件结构