線程安全性:
對象的狀態是指存儲在狀態變量(例如實例和靜態域)中的數據。
對象的狀態可能包括其他依賴對象的域。
例如:某個HashMap的狀態不僅存儲在HashMap對象本身,還存儲在許多Map.Entry對象中。
“共享”意味變量可以由多個線程同時訪問,而“可變”則意味變量的值在其生命周期內可以發生變化。
一個對象的是否需要是線程安全的,取決于它是否被多個線程訪問。要使得線程是安全的,就需要采用同步機制來協同對對象可變專業狀態的訪問。
Java 中的主要同步機制是關鍵字synchronized,它提供了一種獨占的加鎖方式,還有volatile類型的變量,顯式鎖、原子變量。
當多個線程訪問某個類時,不管運行時環境采用何種調度方式或者這些線程將如何交替執行,并且在主調代碼中不需要任何額外的同步或者協同,這個類都能表現出正確的行為,那么這個類就是線程安全的
無狀態的對象一定是線程安全的

內置鎖
Java提供了一種內置的鎖機制來支持鎖機制:同步代碼塊(一個作為鎖的對象引用+一個作為由這個鎖保護的代碼塊)。以synchronized修飾的方法就只一種橫跨整個方法體的同步代碼塊,其中該同步代碼塊的鎖就是方法調用所在的對象。
每個java對象都可以用做一個實現同步的鎖:內置鎖。線程在進入同步代碼塊之前會自動獲得鎖,并且在退出同步代碼塊的時候釋放鎖,不論正常退出還是拋出異常退出,獲得內置鎖的唯一路徑就是進入由這個鎖保護的同步代碼塊或者方法。
java的內置鎖相當于一個互斥鎖,這意味著最多只有一個線程能夠持有這種鎖,當線程A嘗試獲取一個由線程B持有的鎖時,線程A必須等待或者阻塞,直到B釋放這個鎖,如果B不釋放,那么A永遠等下去。
由于每次只能有一個線程執行內置鎖保護的代碼塊,因此,由這個鎖保護的同步代碼塊會以原子方式執行,多個線程在執行該代碼塊時也不會相互干擾。
重入
當某個線程請求一個由其他線程持有的鎖時,發出請求線程的就會阻塞,然而,由于內置鎖是可重入的,因此如果某個線程試圖獲得一個已經由它自己持有的鎖,那么這個請求就會成功。“重入”意味著獲取鎖的操作的粒度是“線程”,而不是“調用”。重入的一種是實現方法是,為每個鎖關聯一個獲取計數值和一個所有者線程,當計數值為0時,這個鎖就被認為是沒有被任何線程持有,當線程請求一個未被持有的鎖時,JVM將記下鎖的持有者,并且將獲取計數值置為1.如果同一個線程再次獲取這個鎖,計數值將遞增,而當線程退出同步代碼塊時,計數器會相應的遞減,當為0時候,這個鎖將被釋放