Synchronize的學習

原文鏈接:https://www.cnblogs.com/paddix/p/5367116.html

基本介紹:
Synchronized是Java中解決併發問題的一種最常用的方法,也是最簡單的一種方法。
主要作用:

  1. 修飾普通方法
  2. 修飾靜態方法
  3. 修飾代碼塊

代碼演示:

1.無Synchronized修飾

public class SyTestDemo {
    public void methods1(){
        System.out.println("methods1.start..");
        try {
            System.out.println("methods1.excute..");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods1.end..");
    }
    public void methods2(){
        System.out.println("methods2.start.." );
        try {
            System.out.println("methods2.excute..");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods2.end..");
    }
    public static void main(String[] args) {
        SyTestDemo testDemo = new SyTestDemo();

        new Thread(new Runnable() {
            @Override
            public void run() {
                testDemo.methods1();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                testDemo.methods2();
            }
        }).start();
    }
}

結果:
輸入1
可以看出線程2在線程1結束前先結束。沒有達到線程1運行完然後線程2在運行的目的。

2.修飾普通方法

代碼演示

public class SyTestDemo2 {
	//方法塊1
    public synchronized void methods1(){
        System.out.println("methods1.start..");

        try {
            System.out.println("methods1.excute..");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods1.end..");
    }
    //方法塊2
    public synchronized void methods2(){
        System.out.println("methods2.start..");

        try {
            System.out.println("methods2.excute..");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods2.end..");
    }

    public static void main(String[] args) {
        SyTestDemo2 syTestDemo2 = new SyTestDemo2();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods2();
            }
        }).start();
    }
}

結果:
結果2
可以看出結果中是線程1先執行完然後線程2再完成。沒有併發執行的情況產生。

3.修飾靜態方法

代碼演示:

public class SyTestDemo2 {
	//靜態方法1
    public static synchronized void methods1(){
        System.out.println("methods1.start..");

        try {
            System.out.println("methods1.excute..");
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods1.end..");
    }
    //靜態方法2
    public static synchronized void methods2(){
        System.out.println("methods2.start..");

        try {
            System.out.println("methods2.excute..");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("methods2.end..");
    }

    public static void main(String[] args) {
        SyTestDemo2 syTestDemo2 = new SyTestDemo2();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo2.methods2();
            }
        }).start();
    }
}

結果:
演示3
修飾靜態方法相當於修飾類。因爲靜態方法是類的方法而不是對象的方法。所以輸出結果依舊是線程1先執行完,然後線程2執行完,沒有併發執行。

4.修飾對象。

public class SyTestDemo3 {
    //方法塊1
    public void methods1(){
        System.out.println("methods1.start..");
        synchronized (this){
            System.out.println("methods1.excute..");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("methods1.end..");
    }
    //方法塊2
    public void methods2(){
        System.out.println("methods2.start..");
        synchronized (this){
            System.out.println("methods2.excute..");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("method2.end..");
    }

    public static void main(String[] args) {
        SyTestDemo3 syTestDemo3 = new SyTestDemo3();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo3.methods1();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                syTestDemo3.methods2();
            }
        }).start();
    }
}

結果:
結果4
可以從結果中看出:雖然線程1和線程2都進入方法執行。但是線程2在進入同步塊之前,需要等待線程1中同步塊執行完成。

參考博客:Sychronized的學習和底層實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章