[英]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個線程:
tradeCounter.incrementAndGet()
tradeCounter.incrementAndGet()
這完全取決於線程在您的方法中調用指令的順序。
我有一個名為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.