簡體   English   中英

同步塊上的線程執行順序

[英]Thread execution sequence on synchronized block

在下面的代碼中,我試圖找出線程處理同步塊上的執行:

public class ThreadExp {
    public static void main(String[] args) throws InterruptedException {
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r, "Thread1");
        Thread t2 = new Thread(r, "Thread2");
        t1.start();
        t2.start();
    }

}

class MyRunnable implements Runnable {

    @Override
    public void run() {
        callFn();
    }

    private void callFn() {
        System.out.println(Thread.currentThread().getName() + ": entered callSync()");
        synchronized (Thread.currentThread()) {
            System.out.println(Thread.currentThread().getName() + ": inside sync");
            try {
                Thread.currentThread().sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " leaving sync");
        }
        System.out.println(Thread.currentThread().getName() + ": leaving callSync()");
    }
}

實際輸出:

    Thread1: entered callFn()
    Thread2: entered callFn()
    Thread1: inside sync block
    Thread2: inside sync block
// 5000 millisec sleep
    Thread2 leaving sync block
    Thread1 leaving sync block
    Thread2: leaving callFn()
    Thread1: leaving callFn()

而我期望這樣的事情:

Thread1: entered callFn()
Thread2: entered callFn()
Thread1: inside sync block
// 5000 millisec sleep
Thread1 leaving sync block
Thread1: leaving callFn()
Thread2: inside sync block
Thread2 leaving sync block
Thread2: leaving callFn()

總的來說,我認為Thread1將獲得鎖然后進入睡眠狀態。 並且只有在Thread1完成之后,Thread2才能進入同步塊。

您正在線程本身上進行同步:

synchronized (Thread.currentThread())

因此,每個線程都有其自己的鎖,並且它們可以同時執行synchronized塊。

如果希望synchronized塊一次僅由一個線程運行,則需要使用相同的鎖。

在您的示例中,可能只是this ,因為您的兩個線程的Runnable實例相同:

synchronized(this) {...}

輸出將如下所示:

Thread1: entered callSync()
Thread1: inside sync
Thread2: entered callSync()
Thread1 leaving sync
Thread1: leaving callSync()
Thread2: inside sync
Thread2 leaving sync
Thread2: leaving callSync()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM