Java重溫學習筆記,synchronized知識一
阿新 • • 發佈:2021-06-18
一、問題的提出,先看下面程式碼的輸出
public class MyDemo implements Runnable { private static int myCount = 0; public static void main(String[] args) { for (int i = 0; i < 10; i++) { Thread thread = new Thread(new MyDemo()); thread.start(); } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("result: " + myCount); } @Override // 此標籤指明此方法覆蓋父類同名方法。優點是編譯器會幫你檢查父類是否有同名方法,如沒有則報錯。 public void run() { for (int i = 0; i < 100000; i++) { myCount++; } } }
不管你怎樣執行,它的結果不會是10*100000。這是因為線上程在執行過程中,若干執行緒同時修改myCount類變數,程式沒有解決多執行緒訪問共享資料的問題。synchronized就是實現每個執行緒依次排隊操作共享資料的功能。
二、synchronized的使用場景,可以是方法,也可以是程式碼塊
三、下面是修改後的程式碼
方法1. 程式碼塊鎖定。因為myCount是類變數,所以需要對類進行鎖定
public class MyDemo implements Runnable { private static int myCount = 0;public static void main(String[] args) { for (int i = 0; i < 10; i++) { Thread thread = new Thread(new MyDemo()); thread.start(); } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("result: " + myCount); } @Override // 此標籤指明此方法覆蓋父類同名方法。優點是編譯器會幫你檢查父類是否有同名方法,如沒有則報錯。 public void run() { for (int i = 0; i < 100000; i++) { synchronized (MyDemo.class) { myCount++; } } } }
執行結果如下:
%JAVA_HOME%\bin\java "MyDemo" ...
result: 1000000
方法2:方法鎖定。把同步程式碼獨立出來,如下:
public class MyDemo implements Runnable { private static int myCount = 0; public static void main(String[] args) { for (int i = 0; i < 10; i++) { Thread thread = new Thread(new MyDemo()); thread.start(); } try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("result: " + myCount); } // synchronized修飾靜態方法 public synchronized static void method1() { myCount++; } @Override // 此標籤指明此方法覆蓋父類同名方法。優點是編譯器會幫你檢查父類是否有同名方法,如沒有則報錯。 public void run() { for (int i = 0; i < 100000; i++) { method1(); } } }
它的執行結果與上面是一樣的。
本文章參考:https://www.cnblogs.com/wangwudi/p/12302668.html