Java Array列表同步如果写在一个线程中并在另一个线程中读取

时间:2013-07-25 15:10:00

标签: java android concurrency

我有一个在线程A中运行的控制器类,并组成一个像这样的本地变量列表

主题A

list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);

其中Order是一个java bean,它有几个原始属性,如String,int,long等。

构造此列表后,其引用将传递给Activity的UI线程(线程B)并在那里访问。跨线程通信使用Handler类+ post()方法完成。

所以问题是,我可以在没有同步的情况下从线程B访问列表数据吗?请注意,在线程A中构造之后,根本不会访问/修改列表。它只是像局部变量一样存在,然后传递给线程B.

4 个答案:

答案 0 :(得分:2)

很安全。在消息队列中完成的同步建立了先发生关系。这当然假定您之后不修改地图。此外,如果没有正确的同步,其他线程也不得修改映射中包含的任何对象。

简而言之,如果列表中的任何数据都没有被B以外的其他线程修改,则不需要进一步同步。

答案 1 :(得分:1)

从您提供的上下文中不清楚这是怎么发生的:

list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);

如果它位于构造函数并且 listfinal ,则this引用不会从构造函数中泄漏< strong>和您绝对相信list不会更改(例如使用unmodifiableList装饰器方法)对{{1}的引用无法从其他地方访问实例,也可以不使用同步。否则你的头上会有达摩克斯之剑。

我提到了Order引用,因为如果从其他地方更改它们,可能不会出现异常,但可能会导致数据不一致/损坏。

答案 2 :(得分:0)

如果您可以保证列表不会被修改,那么您不需要同步,因为所有线程将始终看到相同的列表。

答案 3 :(得分:-3)

是的,如果您只是要阅读数据,则无需同步。

请注意,即使线程A最终将修改列表,而线程B(或任何其他数量的线程)正在访问它,您仍然不必同步,因为在任何给定时间只有一个编写器。

抱歉,上述声明完全不正确。正如JavaDoc中所述:

  

如果多个线程同时访问ArrayList实例,并且在   至少有一个线程在结构上修改列表,它必须是   外部同步。 (结构修改是任何操作   添加或删除一个或多个元素,或显式调整大小   支持阵列; 仅设置元素的值不是a   结构修改。)

另请注意,我没有考虑元素修改,而是纯粹列出修改。