1. 程式人生 > >鎖重入

鎖重入

另一個 運行 同時 tac 必須 stat demo1 demo color

package com.roocon.thread.t6;

public class Demo {
    /*
    當第一個線程A拿到當前實例鎖後,進入a方法,那麽,線程A還能拿到被當前實例所加鎖的另一個
    同步方法b嗎?是不是只有當線程A釋放了a方法的同步鎖後,才可以去獲取b方法的同步鎖呢?
     */
    public synchronized void a(){
        System.out.println("a");
        b();
    }

    public synchronized void b(){
        System.out.println(
"b"); } public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { Demo demo = new Demo(); demo.a(); } }).start(); } }

運行結果:

a
b

以上結果說明,線程A在釋放方法a的同步鎖之前,是可以重新獲得b方法的同步鎖的。以上代碼僅僅是同一個線程在一個同步方法中去成功調用另一個同步方法,那麽,不同的線程拿同一把對象去加鎖,會怎樣進行呢?

package com.roocon.thread.t6;

public class Demo {
    /*
    當第一個線程A拿到當前實例鎖後,進入a方法,那麽,線程A還能拿到被當前實例所加鎖的另一個
    同步方法b嗎?是不是只有當線程A釋放了a方法的同步鎖後,才可以去獲取b方法的同步鎖呢?
     */
    public synchronized void a(){
        System.out.println("a");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    
public synchronized void b(){ System.out.println("b"); try { Thread.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Demo demo = new Demo(); //Demo demo1 = new Demo(); new Thread(new Runnable() { @Override public void run() { demo.a(); } }).start(); new Thread(new Runnable() { @Override public void run() { demo.b(); } }).start(); } }

運行結果:

a
b

雖然以上運行結果還是a b,但是,由於鎖的是同一個實例,所以,在輸出a之後,要等待5s才會輸出b。若將以上代碼修改為如下,鎖的不是同一個實例:

package com.roocon.thread.t6;

public class Demo {
    /*
    當第一個線程A拿到當前實例鎖後,進入a方法,那麽,線程A還能拿到被當前實例所加鎖的另一個
    同步方法b嗎?是不是只有當線程A釋放了a方法的同步鎖後,才可以去獲取b方法的同步鎖呢?
     */
    public synchronized void a(){
        System.out.println("a");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void b(){
        System.out.println("b");
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Demo demo = new Demo();
        Demo demo1 = new Demo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.a();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                demo1.b();
            }
        }).start();
    }
}

運行結果:

a
b

a b幾乎是同時輸出的。

以上兩個代碼說明,如果多個線程同時去執行同步方法,如果鎖的是同一個實例,那麽必須等當前這個同步方法釋放鎖後,才可以去獲取另一個同步鎖方法。

而如果鎖的不是同一個實例,那麽,兩個同步方法幾乎是可以同時執行。

鎖重入