在併發編程中存在線程安全問題,主要緣由有:存在共享數據,多線程共同操做共享數據。關鍵字synchronized能夠保證在同一時刻,只有一個線程能夠執行某個方法或某個代碼塊,同時synchronized能夠保證一個線程的可見性java
利用鎖的機制來實現同步的(解決數據點不一致性 JMM)編程
private static int m = 0; private Object obj = new Object(); public void test1() { try { synchronized (obj) { TimeUnit.MINUTES.sleep(2); m++; } } catch (InterruptedException e) { e.printStackTrace(); } }
鎖效果與同步靜態方法同樣,都是類級別的鎖,同時只有一個線程能訪問帶有同步類鎖的方法。緩存
public class synchronizedDemo { private static int m = 0; public void test2() { try { synchronized (synchronizedDemo.class) { TimeUnit.MINUTES.sleep(2); m++; } } catch (InterruptedException e) { e.printStackTrace(); } } }
與同步塊的用法一致,表示鎖住整個當前對象實例,只有獲取到這個實例的鎖才能進入這個方法。安全
private static int m = 0; public void test2() { try { synchronized (this) { TimeUnit.MINUTES.sleep(2); m++; } } catch (InterruptedException e) { e.printStackTrace(); } }
可經過工具jconsole和jstack去觀察synchronized的底層以及線程狀況。多線程
方法鎖就是由關鍵字ACC_SYNCHRONIZED實現是否互斥方法,併發
monitor:在jvm規範中每一個對象和類在邏輯上都是和一個監視器(monitor)相關聯的,爲了實現監視器的排他性監視能力,JVM爲每個對象和類都關聯一個鎖,鎖住了一個對象,這就是得到對象相關聯的監視器。
實現原理:某一個線程佔有這個對象的時候,首先monitor的計數器是否是0,若是是0表示尚未線程佔有這個時候線程佔有這個對象,而且對這個對象的monitor+1;若是不爲0表示這個對象已經被其餘線程佔有,這個線程等待。當線程釋放佔有權的時候monitor-1。
注:同一個線程能夠對同一個對象屢次加鎖,+1,+1,重入鎖jvm