本地變量在Java中是線程安全的。在線程方法中使用一個hashmap
聲明線程安全嗎? 對於實施例 -在方法內聲明一個hashmap
void usingHashMap()
{
HashMap<Integer> map = new HashMap<integer>();
}
本地變量在Java中是線程安全的。在線程方法中使用一個hashmap
聲明線程安全嗎? 對於實施例 -在方法內聲明一個hashmap
void usingHashMap()
{
HashMap<Integer> map = new HashMap<integer>();
}
只要參照HashMap對象未發佈(不傳遞到另一種方法),它是線程。
這同樣適用於存儲在地圖中的鍵/值。它們需要是不可變的(創建後不能改變它們的狀態),或者只能在這個方法中使用。
當兩個線程在這裏運行相同的方法usingHashMap()
時,它們沒有任何關係。每個thread
將創建它自己的版本的每個局部變量,並且這些變量將不會以任何方式相互作用
如果變量不是本地的,則它們會附加到實例。在這種情況下,運行相同方法的兩個線程都會看到一個變量,而這不是線程安全的。
public class usingHashMapNotThreadSafe {
HashMap<Integer, String> map = new HashMap<Integer, String>();
public int work() {
//manipulating the hashmap here
}
}
public class usingHashMapThreadSafe {
public int worksafe() {
HashMap<Integer, String> map = new HashMap<Integer, String>();
//manipulating the hashmap here
}
}
雖然usingHashMapNotThreadSafe
兩個線程上的usingHashMapNotThreadSafe
同一實例運行後會看到相同的x。這可能是危險的,因爲線程試圖改變map
!第二,在同一個實例usingHashMapThreadSafe
上運行的兩個線程將看到完全不同的x版本,並且不能相互影響。
@ Francis-謝謝。因此,如果必須選擇'hashtabe'和'hashmap'之間的集合,那麼在這種情況下'hashmap'將是更好的選擇。 – Jayant
關鍵是'HashMap'必須在外部進行同步,而不是依靠內部同步方法。在'Hashtable'中同步每個方法應該處理任何併發問題,這使得線程應用程序變得非常糟糕。如果你認爲你沒有達到外部同步,你應該試試'ConcurrentMap'。 –
我認爲要確保完全併發,應該在任何情況下使用ConcurrentHashMap
。即使它在本地範圍內。 ConcurrentHashMap
執行ConcurrentMap
。分區本質上是一種嘗試,如documentation所述:
該表在內部進行分區以嘗試允許指定數量的併發更新而不存在爭用。因爲在哈希表中放置本質上是隨機的,所以實際的併發性會有所不同。理想情況下,您應該選擇一個值來容納儘可能多的線程,就像同時修改表一樣。使用比您需要的值高得多的值可能會浪費空間和時間,而顯着更低的值可能會導致線程爭用。
這會浪費資源,因爲ConcurrentHashMap是內部分區的,以便進行高效的併發修改。使用ConcurrentHashMap也可能表明,我們試圖處理降低代碼可讀性的多線程問題。 – Dariusz
這一行代碼做了兩件事,當你用一個詞「聲明」來描述它們時,你隱藏了它們之間的區別。該行聲明瞭一個變量,並且它還創建了一個新對象。該語言保證每次函數調用都獲得自己的變量實例,但是要確保該對象不與其他線程共享。只要新的HashMap對象的引用是args和locals,一切都會好起來的;但是如果你將它分配給其他線程可以看到的字段,那麼你可能會遇到麻煩。 –