synchronized基礎

synchronized 例子

例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方法

相關文章
相關標籤/搜索