1. 程式人生 > 其它 >Java重溫學習筆記,synchronized知識一

Java重溫學習筆記,synchronized知識一

一、問題的提出,先看下面程式碼的輸出

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