例1,沒有同步的時候運行同一個對象的同一個方法的結果:ide
public class TestSyn { public void showMsg() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { TestSyn testSyn = new TestSyn(); ExecutorService executorService = Executors.newFixedThreadPool(10); Runnable runnable = new Runnable() { @Override public void run() { testSyn.showMsg(); } }; Runnable runnable2 = new Runnable() { @Override public void run() { testSyn.showMsg(); } }; executorService.execute(runnable); executorService.execute(runnable2); executorService.shutdown(); } }
結果:函數
能夠看到,是同時在執行一個方法裏面的內容,沒有進行同步spa
例2,當咱們其它不變,只是在方法上加synchronized後:線程
public class TestSyn { public synchronized void showMsg() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } }
結果:3d
能夠看到是一個方法執行完後再執行下一次,已經進行了同步code
例3,咱們在添加另一個synchronized後觀察運行結果:對象
public class TestSyn { public synchronized void showMsg() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void showMsg2() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { TestSyn testSyn = new TestSyn(); ExecutorService executorService = Executors.newFixedThreadPool(10); Runnable runnable = new Runnable() { @Override public void run() { testSyn.showMsg(); } }; Runnable runnable2 = new Runnable() { @Override public void run() { testSyn.showMsg2(); } }; executorService.execute(runnable); executorService.execute(runnable2); executorService.shutdown(); } }
發不一樣的兩個方法依然進行了同步。blog
咱們從新新建一個對象,執行相同的同步函數觀察結果:繼承
public class TestSyn { public synchronized void showMsg() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { TestSyn testSyn = new TestSyn(); TestSyn testSyn2 = new TestSyn(); ExecutorService executorService = Executors.newFixedThreadPool(10); Runnable runnable = new Runnable() { @Override public void run() { testSyn.showMsg(); } }; Runnable runnable2 = new Runnable() { @Override public void run() { testSyn2.showMsg(); } }; executorService.execute(runnable); executorService.execute(runnable2); executorService.shutdown(); } }
發現不一樣對象的同一個方法沒有進行同步get
例4,咱們換成一個static方法添加synchronized後:
public class TestSyn { public synchronized void showMsg() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized static void showMsg2() { try { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); Thread.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { TestSyn testSyn = new TestSyn(); ExecutorService executorService = Executors.newFixedThreadPool(10); Runnable runnable = new Runnable() { @Override public void run() { testSyn.showMsg(); } }; Runnable runnable2 = new Runnable() { @Override public void run() { TestSyn.showMsg2(); } }; executorService.execute(runnable); executorService.execute(runnable2); executorService.shutdown(); } }
發現又沒有進行同步了。
1.某個對象實例內,synchronized aMethod(){}關鍵字能夠防止多個線程訪問對象的synchronized方法(若是一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不一樣的對象實例的synchronized方法是不相干擾的。也就是說,其它線程照樣能夠同時訪問相同類的另外一個對象實例中的synchronized方法
2.是某個類的範圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它能夠對類的全部對象實例起做用
3.若是同一對象兩個synchronized方法一個是非static方法和static方法,是不相干擾的
4.synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中並不自動是synchronized f(){},而是變成了f(){}。繼承類須要你顯式的指定它的某個方法爲synchronized方法