在Java中,每個對象都擁有一個鎖標記(monitor),也稱爲監視器,多線程同時訪問某個對象時,線程只有獲取了該對象的鎖才能訪問。安全
在Java中,可使用synchronized關鍵字來標記一個方法或者代碼塊,當某個線程調用該對象的synchronized方法或者訪問synchronized代碼塊時,這個線程便得到了該對象的鎖,其餘線程暫時沒法訪問這個方法,只有等待這個方法執行完畢或者代碼塊執行完畢,這個線程纔會釋放該對象的鎖,其餘線程才能執行這個方法或者代碼塊。多線程
1)當一個線程正在訪問一個對象的synchronized方法,那麼其餘線程不能訪問該對象的其餘synchronized方法。這個緣由很簡單,由於一個對象只有一把鎖,當一個線程獲取了該對象的鎖以後,其餘線程沒法獲取該對象的鎖,因此沒法訪問該對象的其餘synchronized方法。併發
2)當一個線程正在訪問一個對象的synchronized方法,那麼其餘線程能訪問該對象的非synchronized方法。這個緣由很簡單,訪問非synchronized方法不須要得到該對象的鎖,假如一個方法沒用synchronized關鍵字修飾,說明它不會使用到臨界資源,那麼其餘線程是能夠訪問這個方法的,spa
3)若是一個線程A須要訪問對象object1的synchronized方法fun1,另一個線程B須要訪問對象object2的synchronized方法fun1,即便object1和object2是同一類型),也不會產生線程安全問題,由於他們訪問的是不一樣的對象,因此不存在互斥問題。線程
另外,每一個類也會有一個鎖,它能夠用來控制對static數據成員的併發訪問。對象
而且若是一個線程執行一個對象的非static synchronized方法,另一個線程須要執行這個對象所屬類的static synchronized方法,此時不會發生互斥現象,由於訪問static synchronized方法佔用的是類鎖,而訪問非static synchronized方法佔用的是對象鎖,因此不存在互斥現象。資源
有一點要注意:對於synchronized方法或者synchronized代碼塊,當出現異常時,JVM會自動釋放當前線程佔用的鎖,所以不會因爲異常致使出現死鎖現象。it