synchronized
翻譯爲中文的意思是同步的,它是Java
中處理線程安全問題經常使用的關鍵字。也有人稱其爲同步鎖。既然是鎖,其必然有鎖的東西,下面先會簡單介紹一下synchronized
,再經過一個示例代碼展現synchronized
鎖了什麼。(這裏先提早透露答案synchronized
鎖的是代碼)安全
synchronized
提供的同步機制確保了同一個時刻,被修飾的代碼塊或方法只會有一個線程執行。ide
synchronized
能夠修飾方法和代碼塊:測試
根據修飾狀況,分爲對象鎖和類鎖:this
對象鎖:線程
this
)類鎖翻譯
Class
對象)Class
對象synchronized
底層原理是使用了對象持有的監視器(monitor
)。可是同步代碼塊和同步方法的原理存在一點差別:code
monitorenter
和monitorexit
指令實現的ACC_SYNCHRONIZED
標識隱式實現,實際上仍是調用了monitorenter
和monitorexit
指令一個特殊的計數器,自增方法increase()
被synchronized
修飾,而獲取當前值方法getCurrent()
則沒有被synchronized
修飾。對象
/** * 計數器 * @author RJH * create at 2019-03-13 */ public class Counter { /** * 全局對象,總數 */ private static int i = 0; /** * 自增 * @return */ public synchronized int increase() { try { //使用休眠讓結果更明顯 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } return ++i; } /** * 獲取當前值 * @return */ public int getCurrent() { return i; } }
使用自增線程和獲取當前值的線程來驗證synchronized
鎖的是代碼,而不是全局變量get
/** * synchronized鎖了什麼 * @author RJH * create at 2019-03-02 */ public class LockWhatTest { public static void main(String[] args) { Counter counter =new Counter(); IncreaseThread increaseThread1=new IncreaseThread(counter); IncreaseThread increaseThread2=new IncreaseThread(counter); GetThread getThread=new GetThread(counter); increaseThread1.start(); increaseThread2.start(); //直到increaseThread的線程啓動才執行下一步 while (increaseThread1.getState().compareTo(Thread.State.NEW)==0 && increaseThread1.getState().compareTo(Thread.State.NEW)==0){ } getThread.start(); } /** * 自增線程 */ static class IncreaseThread extends Thread{ private Counter counter; public IncreaseThread(Counter counter) { this.counter = counter; } @Override public void run() { System.out.println("After increase:" + counter.increase()+",trigger time:"+System.currentTimeMillis()); } } /** * 獲取當前值的線程 */ static class GetThread extends Thread{ private Counter counter; public GetThread(Counter counter) { this.counter = counter; } @Override public void run() { System.out.println("Current:"+ counter.getCurrent()+",trigger time:"+System.currentTimeMillis()); } } }
Current:0,trigger time:1552487003845 After increase:1,trigger time:1552487008846 After increase:2,trigger time:1552487013848
從測試結果能夠得知同步
從而能夠證實
synchronized
並非鎖定方法內訪問的變量synchronized
鎖定的是同一個監視器對象監視的代碼