簡體   English   中英

原子整數計數器打印順序錯誤

[英]atomic integer counter printing in wrong order

我定義了以下實例變量:

private final AtomicInteger tradeCounter = new AtomicInteger(0);

我有一個名為onTrade的方法,定義如下,由6個線程調用:

public void onTrade(Trade trade) {
    System.out.println(tradeCounter.incrementAndGet());
}

為什么輸出:

2 5 4 3 1 6

代替1 2 3 4 5 6嗎?

我想避免使用同步。

你可以想到

tradeCounter.incrementAndGet();

System.out.println();

作為兩個單獨的陳述。 所以在這里

System.out.println(tradeCounter.incrementAndGet());

基本上有兩個語句,這些語句不是原子的。

想象一下這樣的示例,其中有2個線程:

  1. 線程1調用tradeCounter.incrementAndGet()
  2. 線程2調用tradeCounter.incrementAndGet()
  3. 線程2顯示值2
  4. 線程1顯示值1

這完全取決於線程在您的方法中調用指令的順序。

我有一個名為onTrade的方法,定義如下,由6個線程調用:

 public void onTrade(Trade trade) { System.out.println(tradeCounter.incrementAndGet()); } 

為什么輸出:

2 5 4 3 1 6

代替1 2 3 4 5 6嗎?

為什么不應該將其作為輸出? 還是為什么不3 1 4 6 5 2? 還是其他任何1 2 3 4 5 6的排列?

使用AtomicInteger及其incrementAndGet() AtomicInteger incrementAndGet()方法可確保每個線程獲得一個不同的值,並確保獲得的六個值是連續的,沒有同步。 但這與隨后打印結果值的順序無關

如果希望以與獲得結果相同的順序打印結果,那么同步是最簡單的方法。 在這種情況下,使用AtomicInteger不會比使用普通int (為此特定目的)獲得任何收益:

int tradeCounter = 0;

synchronized public void onTrade(Trade trade) {
    System.out.println(++tradeCounter);
}

另外,也不必擔心打印輸出的順序。 考慮:由於某種原因,輸出順序實際上有意義嗎?

incrementAndGet()以期望的順序增加:1、2、3等。但是, system.out不會沿着incrementAndGet() println()以原子方式調用println() incrementAndGet() 因此,期望隨機排序。

我想避免使用同步。

您無法在這種情況下。

System.out.println(...)和tradeCounter.incrementAndGet()是兩個單獨的操作,最有可能在線程i獲得新值時,其他一些線程可以獲取值並在線程i打印之前將其打印。 這里沒有辦法避免同步(直接或間接)。

暫無
暫無

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

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