Java序列化导致并发修改异常

Java序列化导致并发修改异常,java,serialization,concurrency,Java,Serialization,Concurrency,我的程序每秒更新存储在ArrayList中的几百个对象大约一百次。我已经实现了Java的内置序列化,它工作得很好,除非在对象进行序列化时尝试进行序列化,在这种情况下,我可能需要序列化六次才能工作(每次失败的尝试都会引发异常)。我尝试将arraylist标记为瞬态,但是当我加载序列化文件时,引发了空指针异常。因此,我尝试在no args构造函数中初始化瞬态arraylist,但没有任何帮助。我该怎么办?谢谢。您不能使用foreach语句进行迭代并修改表 尝试使用 for (int i =0;i&l

我的程序每秒更新存储在ArrayList中的几百个对象大约一百次。我已经实现了Java的内置序列化,它工作得很好,除非在对象进行序列化时尝试进行序列化,在这种情况下,我可能需要序列化六次才能工作(每次失败的尝试都会引发异常)。我尝试将arraylist标记为瞬态,但是当我加载序列化文件时,引发了空指针异常。因此,我尝试在no args构造函数中初始化瞬态arraylist,但没有任何帮助。我该怎么办?谢谢。

您不能使用foreach语句进行迭代并修改表

尝试使用

for (int i =0;i<arra.length;i++) 

for(int i=0;i将
ArrayList
复制到一个新实例(使用
new ArrayList()
进行浅拷贝并序列化)。

首先确保已同步访问
ArrayList
,例如,在初始化它时:

List<String> list = Collections.synchronizedList(new ArrayList<String>());
List List=Collections.synchronizedList(新的ArrayList());
当需要序列化时,获取一个由于同步而保持一致的副本:

List<String> copy = new ArrayList<String>(list);
List copy=newarraylist(列表);

现在,您可以安全地序列化此副本,而无需阻止对主列表的访问。

如果您正在遍历集合并同时修改它,请使用迭代器。

假设您确实不希望或不需要序列化列表内容,请声明您的列表成员:

private transient final List<?> things = new ArrayList<Object>();
private transient final List things=new ArrayList();
您将始终使用非空列表


也就是说,从它的声音来看,您对列表本身的更新可能需要考虑其他线程安全问题,例如数据争用和可见性问题。

我使用的是非foreach循环。我可能应该在询问此问题之前尝试静态迭代器。因此,也许您可以同步对数组的访问。因为s是一个ArrayList而不是数组,它提供了危险的建议。在另一个线程中进行并发修改时,这并没有帮助,这里就是这种情况。你能提供更多细节吗?比如一些代码?我认为在无参数构造函数中初始化临时ArrayList应该有效,所以我对它是否有效感到困惑esn't.@Robin-反序列化不会调用任何构造函数或成员初始化器。@jtahlborn--那么强制的无参数构造函数有什么意义呢?如果我暂时停止更新ArrayList对象,然后进行序列化,它就可以正常工作。这有什么帮助呢?副本将与serialisati具有所有相同的非线程安全问题在copy.Jed上,这是不正确的。复制的数组将不会被修改(因为它是不同的数据)。除非以非线程安全的方式修改包含的对象本身,否则这将是100%安全的。我的书面异议不是很好,因为复制构造将具有相同的fail-fast语义,但正如公认的答案中所指出的,ArrayList调用
toArray()
在提供的集合的副本构造函数中进行复制。这不会很快失败。不过,您仍然存在线程安全性和可见性问题,应该重新考虑使用共享临时结构。副本本身可能不是线程安全的,这一点很可能是对的。ArrayList的复制构造函数不会以线程安全的方式复制列表。您必须在
synchronized(list)
块中调用该调用。@jtahlborn:ArrayList
的复制构造函数将以线程安全的方式复制它,如果传入的列表按照我的建议由
Collections.synchronizedList()
包装。构造函数调用
toArray()
已被该包装器同步(请参见
ArrayList
源代码)。在这种情况下,使用
synchronize(list)
实际上不会做任何事情,因为包装列表用于同步的对象是内部对象(请参见
Collections
源代码中的
SynchronizedCollection
内部类).您将在不同于保护修改的包装上进行同步。