synchronized對普通同步方法和對靜態方法的區別
阿新 • • 發佈:2019-01-09
synchronized是一個重量級鎖,我們都知道該關鍵字鎖住的是物件而不是程式碼本身,那麼對於靜態方法和同步方法有什麼不同呢,通過如下程式碼進行測試
public class SynchronizedTest { private static int num; private synchronized void test(String param){ if(StringUtils.equals(param,"a")){ num = 100; System.out.println("set " + param + " num over"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else{ num = 200; System.out.println("set " + param + " num over"); } System.out.println("i am : " + param + "; num = " + num); } public static void main(String[] args){ SynchronizedTest s1 = new SynchronizedTest(); SynchronizedTest s2 = new SynchronizedTest(); new Thread(new Runnable() { @Override public void run() { s1.test("a"); } }).start(); new Thread(new Runnable() { @Override public void run() { s2.test("b"); } }).start(); } }
輸出結果為:
set a num over
set b num over
i am : b; num = 200
i am : a; num = 200
Process finished with exit code 0
我們可以看出兩個不同的物件s1和s2並沒有互斥,因為這裡synchronized是分別持有兩個物件的鎖。如果要想m1,m2兩個物件競爭同一個鎖,則需要在method01()上加上static修飾,如下:
public class SynchronizedTest { private static int num; private synchronized static void test(String param){ if(StringUtils.equals(param,"a")){ num = 100; System.out.println("set " + param + " num over"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else{ num = 200; System.out.println("set " + param + " num over"); } System.out.println("i am : " + param + "; num = " + num); } public static void main(String[] args){ SynchronizedTest s1 = new SynchronizedTest(); SynchronizedTest s2 = new SynchronizedTest(); new Thread(new Runnable() { @Override public void run() { s1.test("a"); } }).start(); new Thread(new Runnable() { @Override public void run() { s2.test("b"); } }).start(); } }
執行結果如下:
set a num over
i am : a; num = 100
set b num over
i am : b; num = 200
Process finished with exit code 0
synchronized修飾不加static的方法,鎖是加在單個物件上,不同的物件沒有競爭關係;修飾加了static的方法,鎖是載入類上,這個類所有的物件競爭一把鎖.