文章轉Hollis博客 你們能夠關注下,不少技術類型的文章html
在再有人問你Java內存模型是什麼,就把這篇文章發給他。中咱們曾經介紹過,Java語言爲了解決併發編程中存在的原子性、可見性和有序性問題,提供了一系列和併發處理相關的關鍵字,好比synchronized
、volatile
、final
、concurren包
等。java
在《深刻理解Java虛擬機》中,有這樣一段話:程序員
synchronized
關鍵字在須要原子性、可見性和有序性這三種特性的時候均可以做爲其中一種解決方案,看起來是「萬能」的。的確,大部分併發控制操做都能使用synchronized來完成。算法
海明威在他的《午後之死》說過的:「冰山運動之雄偉壯觀,是由於他只有八分之一在水面上。」對於程序員來講,synchronized
只是個關鍵字而已,用起來很簡單。之因此咱們能夠在處理多線程問題時能夠不用考慮太多,就是由於這個關鍵字幫咱們屏蔽了不少細節。編程
那麼,本文就圍繞synchronized
展開,主要介紹synchronized
的用法、synchronized
的原理,以及synchronized
是如何提供原子性、可見性和有序性保障的等。多線程
synchronized
是Java提供的一個併發控制的關鍵字。主要有兩種用法,分別是同步方法和同步代碼塊。也就是說,synchronized
既能夠修飾方法也能夠修飾代碼塊。併發
/** * @author Hollis 18/08/04. */ public class SynchronizedDemo { //同步方法 public synchronized void doSth(){ System.out.println("Hello World"); } //同步代碼塊 public void doSth1(){ synchronized (SynchronizedDemo.class){ System.out.println("Hello World"); } } }
被synchronized
修飾的代碼塊及方法,在同一時間,只能被單個線程訪問。oracle
synchronized
,是Java中用於解決併發狀況下數據同步訪問的一個很重要的關鍵字。當咱們想要保證一個共享資源在同一時間只會被一個線程訪問到時,咱們能夠在代碼中使用synchronized
關鍵字對類或者對象加鎖。jvm
在深刻理解多線程(一)——Synchronized的實現原理中我曾經介紹過其實現原理,爲了保證知識的完整性,這裏再簡單介紹一下,詳細的內容請去原文閱讀。優化
咱們對上面的代碼進行反編譯,能夠獲得以下代碼:
public synchronized void doSth(); descriptor: ()V flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String Hello World 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return public void doSth1(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=3, args_size=1 0: ldc #5 // class com/hollis/SynchronizedTest 2: dup 3: astore_1 4: monitorenter 5: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 8: ldc #3 // String Hello World 10: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 13: aload_1 14: monitorexit 15: goto 23 18: astore_2 19: aload_1