2016-01-14 60 views
0

我想編寫一個使用get()方法訪問LinkedHashMap的多線程應用程序(應用程序只使用get()方法從LinkedHashMap獲取數據)。源代碼如下:在多線程應用程序中使用LinkedHashMap的get()方法是否安全

public class Thread1 implements Runnable { 
LinkedHashMap<String, ArrayList<GroupMembers>> group; 

public Thread1(LinkedHashMap<String, ArrayList<GroupMembers>> _group) { 
    group = _group 
} 

public void run() { 
    while (true) { 
     Set<String> groupKeyNames = group.keySet(); 
     for (String groupName : groupKeyNames) { 

      ArrayList<GroupMembers> members = group.get(groupName); 
      /* Thread 1 processing */ 
      ... 

     } 
    } 
} 
} 


public class Thread2 implements Runnable { 
LinkedHashMap<String, ArrayList<GroupMembers>> group; 

public Thread2(LinkedHashMap<String, ArrayList<GroupMembers>> _group) { 
    group = _group 
} 

public void run() { 
    while (true) { 
     Set<String> groupKeyNames = group.keySet(); 
     for (String groupName : groupKeyNames) { 

      ArrayList<GroupMembers> members = group.get(groupName); 
      /* Thread 2 processing */ 
      ... 

     } 
    } 
} 
} 

public class Sample { 

    public static void main(String[] args) throws IOException { 

     /* Init LinkedHashMap */ 
     LinkedHashMap<String, ArrayList<GroupMembers>> group; 
     group.put("group1", new ArrayList<GroupMembers>()); 
     group.put("group2", new ArrayList<GroupMembers>()); 
     ... 
     Thread1 t1 = new Thread(group); 
     t1.start(); 
     Thread1 t1 = new Thread(group); 
     t2.start(); 
    } 
} 

在上面的多線程應用程序中使用LinkedHashMap.get()是否安全?

+0

如果Map是有效的final_,並且_safely published_(看起來那些),那麼是的,沒有同步就可以get()從它中取出。當兩個或更多線程訪問相同的數據時,線程安全只是一個問題,並且其中一個或多個線程會更新它。 –

+0

此代碼不起作用,因爲您在插入值之前未將值賦給'group'。你如何初始化它? –

+0

爲什麼你得到'keySet',迭代獲取'members'?如果您在迭代過程中需要組名稱,則只需迭代'group.values()'或'group.entrySet()'就會更容易。 –

回答

2

引述Javadoc

注意,此實現不是同步的。如果多個線程同時訪問鏈接的哈希映射,並且至少有一個線程在結構上修改了映射,則它必須在外部同步。

...

在插入順序鏈接的哈希映射中,僅更改與已經包含在地圖中的鍵關聯的值不是結構上的修改。在訪問順序鏈接的哈希映射中,僅查詢與獲取地圖是一個結構性的改變

無論是插入順序還是訪問順序取決於你如何實際初始化 - 這是不包括的問題:如果你構建LinkedHashMap使用new LinkedHashMap(int, float, boolean),也可能是訪問順序(如果你通過true爲布爾參數),在這種情況下,將是線程安全的

  • 如果使用任何其他構造函數構造它(或通過false作爲布爾參數),它將是線程安全的 - 前提是您也不要繼續在其他任何地方使用groups引用。
+0

我認爲javadoc澄清說,在這種情況下訪問有序的LHM是不安全的 - 但我沒有看到它說一個非訪問順序的LHM將是安全的... – assylias

0

如果你對線程安全的,因爲你不使用「同步」上criticla部分(在那裏你想要的線程安全的代碼塊)塊,除了重複你的代碼將打破關注。 如果您需要保留地圖的排序,您應該使用SortedMap。除迭代外,您可以使用線程安全的ConcurrentSkipListMap,或者與synchronizedSortedMap.section結合使用的另一個SortedMap。 this鏈接可能會有幫助。

相關問題