1. 程式人生 > >深入理解synchronized方法同步的是方法還是物件?

深入理解synchronized方法同步的是方法還是物件?

一.運用synchronized關鍵字

首先我們來看看一個多執行緒中執行緒不安全的列子

程式碼如下:

共享資料類:

public class NotSynchronizated extends Thread {
    private int num =10;
    @Override
    public void run(){
        try {
            System.out.println("當前執行緒為:"+currentThread().getName());
            num--;
            System.out.println(
"num的值為:"+num); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }

執行緒測試類:

public class Text {

    public static void main(String[] args) {
        //將共享資料放入3個執行緒裡進行處理
        NotSynchronizated notSynchronizated = new NotSynchronizated();
        Thread t1
=new Thread(notSynchronizated,"A"); Thread t2=new Thread(notSynchronizated,"B"); Thread t3=new Thread(notSynchronizated,"C"); Thread t4=new Thread(notSynchronizated,"D"); t1.start(); t2.start(); t3.start(); t4.start(); } }

在這個列子中run方法沒有使用關鍵字synchronized,那麼就會造成執行緒不安全,結果如下:

 

那麼當我們使用關鍵字synchronized後結果就會同步了,結果如下:

 

那麼,在這裡是對這個run方法進行了同步呢?還是對這個物件進行了同步呢?

二.synchronized同步的是物件

 為了證明synchronized同步的是物件,我們舉出下面的程式碼:

共享資源類:

public class SynchronizatedObject extends Thread {
    private int num=20;
    @Override
    public synchronized void run(){

        System.out.println("當前的執行緒為"+currentThread().getName());
        num--;
        System.out.println("當前num為"+num);
    }

}

 測試類:

public class Text {

    public static void main(String[] args) {
        SynchronizatedObject synchronizatedObject1=new SynchronizatedObject();//建立第一個資源共享類
        SynchronizatedObject synchronizatedObject2=new SynchronizatedObject();//建立第二個資源共享類
        Thread t1=new Thread(synchronizatedObject1,"A");//加入
        Thread t2=new Thread(synchronizatedObject2,"B");//加入
        t1.start();
        t2.start();
    }
}

結果如下:

從這裡明顯看出這個synchronized關鍵字同步的是物件而不是方法,

如果同步的是方法那麼他將不會出現這種執行緒不安全的情況,而是兩物件一個一個按順序的進入這個同步的方法裡,

出現這中情況,只能說明他是物件同步的。

所以說這段程式碼意思是我建立了兩個物件,同時我也建立了兩把物件鎖來同步話各自的run方法,只不過每一條執行緒的呼叫順序不同才會出現這樣的結果。

總結:synchronized關鍵字同步的是物件不是方法