簡體   English   中英

如何實現一個可以使用Java安全遞增的多線程變量?

[英]How do I implement a multi-threaded variable that I can safely increment using Java?

在我的程序中,我有一個線程將供應變量遞增2,然后另一個線程從供應類中獲取隨機數量的供應。 供應類最多只能存儲5個值,並且由於睡眠和供應請求是隨機的,因此供應計數可以超過其最大限制。

我要確保的是它沒有超過這個限制。

有一個更好的方法嗎?

(偽代碼)

  1. 增加供應2
  2. 如果供應量超過最大值,則將供應量分配給最大值

這是代碼:

private int MAX = 5;
private int supply = 0;
public void run()
{
    while(true) {
      supply = supply + 2;
      if(supply > MAX) 
          supply = MAX;
    }
}

您可以使用公共同步的incSupply()方法來增加供應變量:

public synchronized void incSupply()
{
    // Code borrowed from Jean-Bernard Pellerin.
    int temp = supply + 2;
    if (temp > MAX)
        temp = MAX;
    supply = temp;
}

請注意,對於從'supply'變量讀取/寫入的其他方法,您還需要使用synchronized。

int temp = supply + 2;
if (temp > MAX)
  temp = MAX;
supply = temp;

但這仍然不是線程安全的。 你應該研究鎖和同步。

如果你有多個線程,你應該聲明你的公共資源,(意味着其他線程對該變量執行命令)在你的情況下,我猜是供應,如同步。 並使用細粒度同步

synchronized(this) {
     supply = supply+2
 }

我不完全理解你的問題的這一部分: and the other thread takes a random number of supply from the supply class 這是否意味着消費線程可以從供應類中獲取隨機數量的值,或者是隨機數的值?

在任何情況下,您都有一個需要互斥訪問的資源,因此您需要確保只有一個線程可以修改它。 在java中,這可以通過在被修改的實例上請求內部鎖來輕松完成,只有一個線程可以在任何給定時間保持此鎖。 現在,當一個線程遇到一個synchronized塊時(根據Stelsavva的例子),它會自動嘗試在this代表的任何一個實例上獲得內部鎖,並保持它直到塊的結尾。 如果任何其他線程遇到該塊,而另一個線程持有該鎖,則它將等待另一個線程釋放該鎖。

因此,塊的執行是同步的,你不會遇到交錯問題。

使用具有五個許可證的信號量 有點違反直覺,我認為許可證代表了存儲供應的許可,因此第一個線程需要獲得存儲供應品的許可證。 當第二個線程獲取耗材時,它會釋放許多許可證。

最簡單的解決方案是使用AtomicInteger而不會遇到同步增量的麻煩:

private int MAX = 5;
private AtomicInteger supply = new AtomicInteger(0);
public void run()
{
    while(true) {
      if(supply.addAndGet(2) > MAX) 
          supply.set(MAX);
    }
}

暫無
暫無

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

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