2016-01-14 52 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链接可能会有帮助。

相关问题