非線程安全:在多個線程對同一個對象中的實例進行併發訪問時發生,產生的後果即爲髒讀。java
線程安全:得到的實例變量的值是通過同步處理的,不會出現髒讀現象。安全
非線程安全問題存在於實例變量中,即共享的變量 ,但如果方法內部的私有變量,則不存在非線程安全問題。這是由於方法內部的變量是私有的特性形成的。併發
若是多個線程同時訪問一個對象中的實例變量,則有可能出現非線程安全問題。異步
解決方法:在方法前加關鍵字synchronized便可。在兩個線程訪問同一個對象中的同步方法時必定是線程安全的。jvm
多個對象多個鎖。關鍵字synchronized取得的鎖都是對象鎖,那個線程先訪問帶synchronized關鍵字的方法,那個線程就持有該方法所屬對象的鎖Lock,那麼其餘線程就只能處於等待狀態,前提是多個線程訪問的是同一個對象。ide
Service service = new Service(); Thread t1 = new Thread(service); Thread t2 = new Thread(service); t1.start(); t2.start();
但如果多個線程訪問多個對象,則jvm就會建立多個鎖,則運行結果就是異步的。線程
Service service1 = new Service(); Service service2 = new Service(); Thread t1 = new Thread(service1); Thread t2 = new Thread(service2); t1.start(); t2.start();
若A線程先持有object對象的Lock鎖,B線程能夠以異步的方式調用object對象中的非synchronized方法。code
若A線程先持有object對象的Lock鎖,B線程若是要調用object對象中的synchronized方法則需等待,也就是同步。對象
髒讀:在讀取實例變量時,此值已經被其餘線程更改過了。繼承
synchronized鎖重入:在使用synchronized關鍵字時,當一個線程獲得一個對象鎖後,再次請求此對象鎖時是能夠再次獲得該對象的鎖的。即在一個synchronized方法/塊的內部調用本類的其餘synchronized方法/塊時,是永遠能夠獲得鎖的。
public class Service{ public synchronized methodA(){ methodB(); } public synchronized methodB(){ } }
線程會同步調用methodA--methodB的順序。
可重入鎖:本身能夠再次獲取本身的內部鎖。
可重入鎖也支持在父子類繼承的環境中。當存在父子類繼承關係是,子類是徹底能夠經過可重入鎖的方式調用父類的同步方法。
當一個線程執行的代碼出現異常時,其所持有的鎖會自動釋放。
同步不具備繼承性。因此override父類的synchronized方法仍須要加上synchronized關鍵字。