簡體   English   中英

同步發生一些奇怪的事情(Test2.class)

[英]something strange happen with synchronized (Test2.class)

public class Test2 {
    static int count;
    public static void main(String[] args) {
        final Test2 t1 = new Test2();
        final Test2 t2 = new Test2();

        new Thread(new Runnable() {

            @Override
            public void run() {
                t1.foo();
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                t1.bar();
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                t2.foo();
            }
        }).start();
    }
    public static synchronized void foo() {
        synchronized (Test2.class) {
            System.out.println("run bar"+count++);
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public static synchronized void bar() {
        System.out.println("run bar");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

上面是我嘗試的代碼。當我在一個同步的類(Test2.class)中編寫所有代碼時,發現奇怪的事情發生。調用foo()方法后,我無法立即調用bar()方法。 我認為它鎖定了同一個對象。如何解釋這個奇怪的事情。

您的代碼開始的所有3個線程在Test2類上都獲得相同的鎖。 當您編寫以以下內容開頭的方法時

static synchronized

這意味着它必須獲得對類對象的鎖定。

foo方法中的同步塊是冗余的。 它指定使用與使用靜態同步相同的類來鎖定。 由於內在鎖是可重入的,因此這不會引起問題。

無論如何,您的每個線程都將獲得該鎖,運行完成,然后釋放該鎖。 由於您鎖定的是類而不是實例,因此線程使用哪個Test2實例無關緊要,它們仍然獲取相同的鎖並一次執行一個。

當我運行它時,我得到以下輸出:

c:\Users\ndh>java Test2
run bar0
run bar1
run bar

這些線程的運行順序取決於調度程序。 可以猜想,調用t1.foo的Runnable取得了領先優勢-因為它首先創建並啟動,所以很可能會有一個窗口,在該窗口中不會有任何競爭者獲得該鎖。

暫無
暫無

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

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