簡體   English   中英

兩個線程如何同時進入同步塊?

[英]How could the two threads enter the synchronized block at the same time?

發生了一些奇怪的事情。 當我進入同步塊時,我嘗試打印線程的名稱。在打印語句之后,我暫停了100000秒。

@Override
public int getNextAvailableVm() {
    synchronized(this) {

        System.out.println(Thread.currentThread().getName());

        try {Thread.sleep(100000000);}catch(Exception exc){}

        String dataCenter = dcc.getDataCenterName();
        int totalVMs = Temp_Algo_Static_Var.vmCountMap.get(dataCenter);
        AlgoHelper ah = (AlgoHelper)Temp_Algo_Static_Var.map.get(dataCenter);
        .
        .
        .
   }
}

但是在運行此方法時,將打印兩個線程的名稱。

Thread-11
Thread-13

在此之后,會出現長時間的停頓。 這是為什么 ? 當第一個線程尚未離開同步塊時,兩個線程如何進入同步塊?

如果兩個線程針對同一個對象運行,則不應發生這種情況。

因此,我建議您為每個線程創建一個新對象,或者至少某些線程在不同的對象上運行。

如果你想多個對象,那么你應該使用synchronized(this) ,你應該建立一個static final Object ,以synchronize的。 請不要在this.getClass()上同步,因為這樣會中斷。

您很可能在包含類的不同實例上調用getNextAvailableVm() 由於您正在this進行同步, this您將鎖定在兩個不同的監視器上(第一個線程鎖定在instance1上,第二個鎖定在instance2上)。

有很多方法可以糾正此問題:

  • 使整個方法synchronized
  • this.getClass()上同步
  • 定義要鎖定的靜態對象
  • 使用java.util.concurrent.locks中的方法進行鎖定

這些只是解決您的問題的一些建議,但是要找到合適的建議,我們將必須了解有關您的應用程序結構和需求的更多信息。

我猜下面的編會像您預期的那樣工作,

鎖定在Thread1.Class上,兩個線程不會同時執行該方法

public class Test {
    public static void main(String [] args) { 
        Thread1 t1 = new Thread1();
        Thread1 t2 = new Thread1();
        t1.start();
        t2.start();
    }
}

class Thread1 extends Thread{
    public void run(){
        getNextAvailableVm();
    }
    public void getNextAvailableVm() {
        synchronized(Thread1.class) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
                }catch(Exception exc){}
            System.out.println(Thread.currentThread().getName());
        }

    }
}

輸出線程1線程1線程0線程0

暫無
暫無

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

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