簡體   English   中英

線程中的靜態同步和非靜態同步方法

[英]static synchronized and non static synchronized methods in threads

可以任何人解釋聲明......“靜態同步方法和非靜態同步方法不會相互阻塞 - 它們可以同時運行”

static synchronized void test() { foo(); }

等於

static void test() { synchronized(MyClass.class) { foo(); } }

synchronized void test() { foo(); }

等於

void test() { synchronized(this) { foo(); } }

這意味着:靜態方法鎖定類的類對象。 非靜態方法鎖定它們被調用的實例(默認情況下,也可以synchronized(anyOtherLock) )。 由於它們鎖定不同的對象,因此它們不會相互阻擋。

靜態方法和非靜態方法上的鎖定對象是不同的。 靜態方法使用Class對象作為鎖(lock obj: MyClass.class ),而非靜態方法使用實例對象作為鎖定,此時方法的調用被綁定到該鎖(lock obj: this ) 。

非靜態同步方法將監視器鎖定在'this'上 - 這意味着只有當前對象被鎖定。因此,如果任何一個線程正在訪問非靜態同步方法,則將阻止與當前對象關聯的所有線程訪問該類的非靜態同步方法。 而其他對象的線程仍然可以訪問方法。

靜態同步方法將監視器鎖定放在Class對象上 - 這意味着如果任何對象的線程正在訪問該方法,則所有線程都將被阻止以訪問該類的所有靜態同步方法。

公共類TestSync {

public synchronized void n1(int threadId)
{
    snooze(threadId);
    System.out.println("Sync non static n1 " + threadId);
}

public void n2(int threadId)
{ 
    snooze(threadId);
    System.out.println(" non static n2 " + threadId);
}

public static synchronized void s1(int threadId)
{
    snooze(threadId);
    System.out.println("Sync static s1 "+  threadId);
}

public static void s2(int threadId)
{
    snooze(threadId);
    System.out.println(" static s2 "+  threadId);
}

static void snooze(int threadId)
{
    System.out.println("Waiting ... "+ threadId);
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    TestSync ob = new TestSync();
    TestSync ob2=new TestSync();
    TestSync ob3=new TestSync();
    TestSync ob4=new TestSync();

    Runnable r1=()-> {
        /*ob.n1(10);
        ob.n2(10);*/
        ob.s1(10);
        //ob.s2(10);
    };

    Runnable r3=()-> {
        /*ob2.n1(30);
        ob2.n2(30);*/
        ob2.s1(30);
        //ob2.s2(30);
    };

    Runnable r4=()-> {
        /*ob3.n1(40);
        ob3.n2(40);*/
        ob3.s1(30);
        //ob3.s2(30);
    };

    Thread t1=new Thread(r1);
    Thread t2= new Thread(r2);
    Thread t3= new Thread(r3);
    Thread t4= new Thread(r4);
    Thread t5= new Thread(r5);
    t1.start();
    t3.start();
    t4.start();

}

運行一次for static synchronized,然后在runnable和run中取消注釋非靜態同步調用(和注釋靜態同步)。 你會明白的。

暫無
暫無

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

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