對於多線程(併發)和Spring Boot這兩塊在同步進行學習中,在看到使用synchronized關鍵字使操做同步時,看到和C#中不同的東西,因此這裏呢,就深刻學習了下,如有錯誤之處,還望指正。java
咱們知道因爲併發會致使線程不安全的問題,此時咱們手段之一採起線程同步,也就是說使得全部併發線程在執行中保持同步的過程,當方法聲明爲同步時,傳遞到同步塊中的對象稱之爲監視器或鎖定對象,若是有另一個線程也在執行該同步方法,那麼該線程將被阻塞,直到線程釋放該監視器或鎖定對象。咱們在類中已定義的方法或塊上使用synchronized關鍵字,同時synchronized關鍵字不能與類定義中的變量或屬性一塊兒使用。安全
所謂的對象級別鎖,也就是針對非靜態方法執行同步塊鎖定,那麼同步塊中的監視器或鎖定對象則是基於對象實例,有以下三種形式多線程
class Test { public synchronized void LockMethod() { } }
或者併發
class Test { public void LockMethod() { synchronized(this) { } } }
或者學習
class Test { private final Object lock = new Object(); public void LockMethod() { synchronized (lock) { } } }
若在同步方法中存在靜態數據,爲保持靜態數據線程安全,咱們則需使用類級別鎖,這意味着,若是在運行時有多個實例的Test,則一次只能在一個實例中的一個線程上執行一個線程LockMethod(),而全部其餘實例將被其餘線程鎖定。針對類級別鎖,那麼同步塊中監視器或鎖定對象有以下三種形式:this
class Test { public synchronized static void LockMethod() { } }
或spa
class Test { public void LockMethod() { synchronized (Test.class) { } } }
或線程
class Test { private final static Object lock = new Object(); public void LockMethod() { synchronized (lock) { } } }
在這裏我主要是看到了上述第二種形式中所使用的鎖定對象,因爲java和C#語法大多類似,可是這在C#中找不到可對比的東西,我不明白這究竟是什麼個意思,因此就深刻看了些,本覺得能夠直接查看源碼,然而並無任何反應,看來就是Java中自然存在的了,我去打印發現和獲取實例的類名的結果是同樣的,咱們將這種狀況翻譯爲className.class,這究竟是什麼意思呢?爲什麼上述第二種形式就是類級別鎖定從而保證線程安全了呢?翻譯
System.out.println(Test.class.toString()); System.out.println(new Test().getClass());
因而乎我想到看一下所購買的《深刻理解Java虛擬機》中對於類加載原理的解釋,結果發現:在類加載時機的第一階段也就是加載階段,虛擬機會完成3件事情,其中最後一件事情則是在內存中生成一個對應類的java.lang.Class對象,做爲方法區這個類的各類數據的入口。換句話說,每一個類在JVM中有且只會有惟一的一個java.lang.Class對象實例,因此我大膽猜想className.class就是獲取java.lang.Class對象惟一實例的引用,如此一來就保證始終只有一個線程可以進入同步塊。code
本節咱們經過對關鍵字synchronized實現線程同步作了詳細瞭解,其實並不難,這裏我想表達的是看到和C#中不同的東西,也就是className.class具體是什麼意思,同時在用java實現單例模式中也有這種狀況,因此詳細學習了下,也作個備忘錄,可能對大部分學java的童鞋而言確實很簡單,我仍是處於初級階段,也是在一步步深刻的學習。