在线程A中,ArrayList
创建了一个。它仅从线程A进行管理。在线程B中,我想将其复制到新实例。
要求是不copyList
应该失败,并且应该返回列表的一致版本(至少在复制过程中有时存在=)。
我的方法是这样的:
public static <T> ArrayList<T> copyList(ArrayList<? extends T> list) {
List<? extends T> unmodifiableList = Collections.unmodifiableList(list);
return new ArrayList<T>(unmodifiableList);
}
问题1:是否满足要求?
问题2:如何在没有Collections.unmodifiableList
适当的迭代器和try-catch块的情况下执行相同的操作?
UPD。那是我一年前被问到的面试问题。我理解在多线程环境中使用非线程安全的集合(例如ArrayList)是一个坏主意
如果“拥有”线程不提供某种协议来创建纯ArrayList的副本,则绝对没有办法。
如果没有任何协议,线程A可以在可能修改的列表的任何时间,这意味着线程B从来没有得到一个机会,以确保是看到了列表的一致状态。
为了实际允许进行一致的复制,线程A必须确保对其所做的任何修改都将写入内存,并且对其他线程可见。
通常,如果执行程序的线程内部没有差异,则允许VM重新排列指令,进行适当的读写操作。例如,这包括通过将值保存在CPU寄存器或本地堆栈中来延迟写入。
确保所有内容始终写入主菜单的唯一方法是使线程A执行对VM提出重新排序障碍的指令(例如,同步块或易失性字段访问)。
因此,如果没有线程A的合作,就无法确保满足上述条件。
规避此问题的常见方法是仅通过以安全包装的形式使用List来同步对List的访问(Collections.synchronizedCollection),或者使用内置了这些保证的List实现(任何类型的并发list实现)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句