簡體   English   中英

當少數線程嘗試調用相同的同步方法時會發生什么?

[英]What happens when few threads trying to call the same synchronized method?

所以我參加了這場賽馬,當一匹馬到達終點線時,我調用了到達方法。 假設我有10個線程,每匹馬一個,而第一個到達的馬確實調用了“到達”:

public class FinishingLine {
    List arrivals;
    public FinishingLine() {
        arrivals = new ArrayList<Horse>();
    }

    public synchronized void arrive(Horse hourse) {
        arrivals.add(hourse);
    }
}

我將Ofc方法設置為“同步”,但我不完全了解如果不同步會發生什么,這位教授只是說這並不安全。

我想更好地理解的另一件事是,如何確定第一個線程完成后將使用哪個線程? 第一個線程完成“到達”並且方法解鎖后,下一個線程將運行?

1)行為將是不確定的,但是您應該假定它不是您希望它以任何可以依賴的方式進行的行為。

如果兩個線程嘗試同時添加,則可能同時添加了兩個元素(以任一順序),僅添加了一個元素,或者甚至都沒有添加。

Javadoc的相關引用是:

請注意,此實現未同步 如果多個線程同時訪問ArrayList實例,並且至少有一個線程在結構上修改列表,則必須在外部進行同步。 (結構修改是添加或刪除一個或多個元素或顯式調整后備數組大小的任何操作;僅設置元素的值不是結構修改。)

2)這取決於操作系統如何調度線程。 對於常規同步塊,不能保證“公平”(按到達順序執行),盡管有某些類( 信號量是一種)可以選擇公平執行順序。

例如,您可以使用信號量實施公平的執行命令:

public class FinishingLine {
    List arrivals;
    final Semaphore semaphore = new Semaphore(1, true);

    public FinishingLine() {
        arrivals = new ArrayList<Horse>();
    }

    public void arrive(Horse hourse) {
        semaphore.acquire();
        try {
          arrivals.add(hourse);
        } finally {
          semaphore.release();
        }
    }
}

但是,使用公平的阻塞隊列來完成此操作會更容易,該隊列為您處理並發訪問:

public class FinishingLine {
  final BlockingQueue queue = new ArrayBlockingQueue(NUM_HORSES, true);

  public void arrive(Horse hourse) {
    queue.add(hourse);
  }
}

暫無
暫無

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

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