的同步建议在遗留应用程序中,我有一个Vector来保存要按时间顺序排列的文件列表,并且多个线程要求它处理下一个文件。 (请注意,我认识到有可能使用更好的集合(可随意推荐),但我现在没有时间来改变这个大小。)需要关于Java Vector/ConcurrentModificationException的同步
在计划的时间间隔内,另一个线程检查工作目录,查看是否有文件因为出错而成为孤儿。如果系统异常繁忙,此线程调用的方法偶尔会引发ConcurrentModificationException。所以我知道至少有两个线程试图立即使用Vector。
这是代码。我相信问题是在返回的Vector上使用clone()。
private synchronized boolean isFileInDataStore(File fileToCheck){
boolean inFile = false;
for(File wf : (Vector<File>)m_dataStore.getFileList().clone()){
File zipName = new File(Tools.replaceFileExtension(fileToCheck.getAbsolutePath(), ZIP_EXTENSION));
if(wf.getAbsolutePath().equals(zipName.getAbsolutePath())){
inFile = true;
break;
}
}
return inFile;
}
的getFileList()的方法如下:
public synchronized Vector<File> getFileList() {
synchronized(fileList){
return fileList;
}
}
作为权宜之计,将改变getFileList方法如下足以返回矢量的副本?
public synchronized Vector<File> getFileListCopy() {
synchronized(fileList){
return (Vector<File>)fileList.clone();
}
}
我必须承认,我一般使用的,因为它涉及到集合,简单地宣告方法,这样是不够的,在Java的同步混淆。作为一个额外的问题,声明方法是同步的,并用另一个同步块包装返回调用只是疯狂的编码?看起来多余。
编辑:这里是触摸列表的其他方法。
public synchronized boolean addFile(File aFile) {
boolean added = false;
synchronized(fileList){
if(!fileList.contains(aFile)){
added = fileList.add(aFile);
}
}
notifyAll();
return added;
}
public synchronized void removeFile(File dirToImport, File aFile) {
if(aFile!=null){
synchronized(fileList){
fileList.remove(aFile);
}
// Create a dummy list so I can synchronize it.
List<File> zipFiles = new ArrayList<File>();
synchronized(zipFiles){
// Populate with actual list
zipFiles = (List<File>)diodeTable.get(dirToImport);
if(zipFiles!=null){
zipFiles.remove(aFile);
// Repopulate list if the number falls below the number of importer threads.
if(zipFiles.size()<importerThreadCount){
diodeTable.put(dirToImport, getFileList(dirToImport));
}
}
}
notifyAll();
}
}
那一行是抛出的异常? – Jivings 2012-03-13 18:40:20
这很难说。纯粹基于你所展示的代码,改变getFileList来返回一个克隆是无济于事的,因为在你使用getFileList的唯一地方,它已经创建了一个克隆。总是返回一个克隆可能会让事情变得更好(但是根据你发布的代码,没有证据表明它是否会发生,也就是说你没有显示整个程序) – 2012-03-13 18:57:02
@Jivings - 它被抛出循环'(文件wf :(矢量)m_dataStore.getFileList()。clone()){' –
user1011251
2012-03-13 19:25:51