java 线程安全list_JAVA并发编程实战-线程安全性
線程安全性:
對象的狀態(tài)是指存儲在狀態(tài)變量(例如實例和靜態(tài)域)中的數(shù)據(jù)。
對象的狀態(tài)可能包括其他依賴對象的域。
例如:某個HashMap的狀態(tài)不僅存儲在HashMap對象本身,還存儲在許多Map.Entry對象中。
“共享”意味變量可以由多個線程同時訪問,而“可變”則意味變量的值在其生命周期內(nèi)可以發(fā)生變化。
一個對象的是否需要是線程安全的,取決于它是否被多個線程訪問。要使得線程是安全的,就需要采用同步機制來協(xié)同對對象可變專業(yè)狀態(tài)的訪問。
Java 中的主要同步機制是關(guān)鍵字synchronized,它提供了一種獨占的加鎖方式,還有volatile類型的變量,顯式鎖、原子變量。
當(dāng)多個線程訪問某個類時,不管運行時環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或者協(xié)同,這個類都能表現(xiàn)出正確的行為,那么這個類就是線程安全的
無狀態(tài)的對象一定是線程安全的
內(nèi)置鎖
Java提供了一種內(nèi)置的鎖機制來支持鎖機制:同步代碼塊(一個作為鎖的對象引用+一個作為由這個鎖保護(hù)的代碼塊)。以synchronized修飾的方法就只一種橫跨整個方法體的同步代碼塊,其中該同步代碼塊的鎖就是方法調(diào)用所在的對象。
每個java對象都可以用做一個實現(xiàn)同步的鎖:內(nèi)置鎖。線程在進(jìn)入同步代碼塊之前會自動獲得鎖,并且在退出同步代碼塊的時候釋放鎖,不論正常退出還是拋出異常退出,獲得內(nèi)置鎖的唯一路徑就是進(jìn)入由這個鎖保護(hù)的同步代碼塊或者方法。
java的內(nèi)置鎖相當(dāng)于一個互斥鎖,這意味著最多只有一個線程能夠持有這種鎖,當(dāng)線程A嘗試獲取一個由線程B持有的鎖時,線程A必須等待或者阻塞,直到B釋放這個鎖,如果B不釋放,那么A永遠(yuǎn)等下去。
由于每次只能有一個線程執(zhí)行內(nèi)置鎖保護(hù)的代碼塊,因此,由這個鎖保護(hù)的同步代碼塊會以原子方式執(zhí)行,多個線程在執(zhí)行該代碼塊時也不會相互干擾。
重入
當(dāng)某個線程請求一個由其他線程持有的鎖時,發(fā)出請求線程的就會阻塞,然而,由于內(nèi)置鎖是可重入的,因此如果某個線程試圖獲得一個已經(jīng)由它自己持有的鎖,那么這個請求就會成功。“重入”意味著獲取鎖的操作的粒度是“線程”,而不是“調(diào)用”。重入的一種是實現(xiàn)方法是,為每個鎖關(guān)聯(lián)一個獲取計數(shù)值和一個所有者線程,當(dāng)計數(shù)值為0時,這個鎖就被認(rèn)為是沒有被任何線程持有,當(dāng)線程請求一個未被持有的鎖時,JVM將記下鎖的持有者,并且將獲取計數(shù)值置為1.如果同一個線程再次獲取這個鎖,計數(shù)值將遞增,而當(dāng)線程退出同步代碼塊時,計數(shù)器會相應(yīng)的遞減,當(dāng)為0時候,這個鎖將被釋放
總結(jié)
以上是生活随笔為你收集整理的java 线程安全list_JAVA并发编程实战-线程安全性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux syslog 删除文件_Li
- 下一篇: linux创建a1的硬链接a2,Linu