2013-06-05 15 views
10

所以我只是在某些Java代碼中使用saw someone try to use a ThreadLocal<AtomicInteger>
現在,對於鏈接的代碼,這顯然沒有用處,導致請求被拒絕的其他問題。可能ThreadLocal <AtomicInteger>可能有用嗎?

而且它似乎總是沒用:AtomicInteger(來自java.util.concurrent.atomic包)是專門爲多線程訪問而設計的,而ThreadLocal使得每個線程都有自己的值,所以爲什麼要用它呢?

我的問題是:有沒有任何情況下ThreadLocal<AtomicInteger>會有用?

+0

不是一個有趣的評論 - 但我真的想不出任何。我同意你的推理,並認爲它排除了ThreadLocal 有用的任何情況。 – selig

+0

除非使用反射,否則無法訪問另一個線程的threadlocal。 –

回答

6

是的,我們可以拿出一個合理的方案:

  1. 我們在每個任務的開始需要的AtomicInteger線程本地實例;
  2. 我們繼續在其他幾個線程中分配這個對象,例如主任務線程派生的子線程。

沒有評估出現的上下文的總體情況,我們無法判斷。

+0

1.這是說我們可能需要這樣做,因爲我們可能需要這樣做嗎?但是在這種情況下,使用ThreadLocal開始是明智的。 雖然我同意,如果沒有明確的上下文,很難將事情排除在外。 – selig

+0

@selig如果所有這些都發生在服務器代碼中,則每個客戶端請求都由其自己的線程隔離服務,並且該主線程啓動它自己的線程組並分發'AtomicInteger',這可能需要從以前的任務中重用(它每次都不是新鮮的物體)。是的,這是一個延伸,但這並不重要:一旦你有需要,你有了它,而你沒有犯罪。 –

+0

是的,這聽起來像一個合法的場景(多線程服務器,一個線程/客戶端交給多個工作人員)。如果有更好的答案出現,我會拒絕接受。 – Riking

4

假設我們需要每個線程的整數計數器。 ThreadLocal的可以使用對象只工作,所以在邏輯上我們需要使用一個int包裝 - 整數

ThreadLocal<Integer> count = new ThreadLocal<>(); 
... 
count.set(count.get() + 1); 

alternatavely我們可以使用的AtomicInteger,不是因爲它的線程安全的,但因爲它是可變的

ThreadLocal<AtomicInteger> count = new ThreadLocal<>(); 
... 
count.get().incrementAndGet(); 

版本2的比版本1好得多,這是一個真正的性能殺手

+0

好點。我使用AtomicReference 將結果對象從Runnable中的代碼傳遞迴調用者 - 並不是因爲我需要原子性,而是因爲我需要一個可變引用,而且我懶得爲此創建一個類。 – Durandal

+0

那麼只是爲了有一個精心編寫的包裝?也許stdlib應該提供一個MutableInteger類或其他東西。 – Riking

+1

'AtomicInteger'使用'volatile'和一些同步引擎。所以我不清楚在這種情況下它的開銷與'Integer'的開銷相比。你有沒有檢查「版本1是一個真正的性能殺手」聲明與適當的基準? – Vadzim

1

我認爲只有ThreadLocal<AtomicInteger>的異國情調的原因。可能有些情況下,ThreadLocal不是唯一參考AtomicInteger,以便更多的線程可以訪問它。當你發現自己在這種情況下,我想你最好有在你的設計仔細一看......

如果你做不需要AtomicInteger線程安全的,而只是它的可變性,我更喜歡使用的int[]AtomicInteger加上完全控制:

ThreadLocal<int[]> count = new ThreadLocal<>(); 
... 
count.set(new int[1]); 
... 
count.get()[0] = 42; 
... 
count.get()[0] += 4711;