我有一个在线程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.
答案 0 :(得分:2)
很安全。在消息队列中完成的同步建立了先发生关系。这当然假定您之后不修改地图。此外,如果没有正确的同步,其他线程也不得修改映射中包含的任何对象。
简而言之,如果列表中的任何数据都没有被B以外的其他线程修改,则不需要进一步同步。
答案 1 :(得分:1)
从您提供的上下文中不清楚这是怎么发生的:
list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);
如果它位于构造函数并且 list
为final
且,则this
引用不会从构造函数中泄漏< strong>和您绝对相信list
不会更改(例如使用unmodifiableList
装饰器方法)和对{{1}的引用无法从其他地方访问实例,也可以不使用同步。否则你的头上会有达摩克斯之剑。
我提到了Order
引用,因为如果从其他地方更改它们,可能不会出现异常,但可能会导致数据不一致/损坏。
答案 2 :(得分:0)
如果您可以保证列表不会被修改,那么您不需要同步,因为所有线程将始终看到相同的列表。
答案 3 :(得分:-3)
是的,如果您只是要阅读数据,则无需同步。
请注意,即使线程A最终将修改列表,而线程B(或任何其他数量的线程)正在访问它,您仍然不必同步,因为在任何给定时间只有一个编写器。
抱歉,上述声明完全不正确。正如JavaDoc中所述:
如果多个线程同时访问ArrayList实例,并且在 至少有一个线程在结构上修改列表,它必须是 外部同步。 (结构修改是任何操作 添加或删除一个或多个元素,或显式调整大小 支持阵列; 仅设置元素的值不是a 结构修改。)
另请注意,我没有考虑元素修改,而是纯粹列出修改。