Java 并发异常 private static HashMap sFileInfoObjectList=new CacheLinkedHashMap(); 公共静态同步FileInfo getFileInfoForProvider(…){ FileInfo foundFileInfo=null; (...) foundFileInfo=sFileInfoObjectList.get(hashEntryKey); (...) sFileInfoObjectList.put(hashEntryKey、foundFileInfo); (...) } public static synchronized void removeFileInfoForProvider(final int providerId){ 线程线程=新线程(){ @凌驾 公开募捐{ 迭代器it=sFileInfoObjectList.entrySet().Iterator(); while(it.hasNext()){ 条目对=it.next(); FileInfo=pair.getValue(); 如果(providerId==info.mProvider){ it.remove(); } } } }; }

Java 并发异常 private static HashMap sFileInfoObjectList=new CacheLinkedHashMap(); 公共静态同步FileInfo getFileInfoForProvider(…){ FileInfo foundFileInfo=null; (...) foundFileInfo=sFileInfoObjectList.get(hashEntryKey); (...) sFileInfoObjectList.put(hashEntryKey、foundFileInfo); (...) } public static synchronized void removeFileInfoForProvider(final int providerId){ 线程线程=新线程(){ @凌驾 公开募捐{ 迭代器it=sFileInfoObjectList.entrySet().Iterator(); while(it.hasNext()){ 条目对=it.next(); FileInfo=pair.getValue(); 如果(providerId==info.mProvider){ it.remove(); } } } }; },java,concurrency,synchronized,concurrentmodification,synchronized-block,Java,Concurrency,Synchronized,Concurrentmodification,Synchronized Block,我在run()方法中得到一个concurentModificationException。我尝试了以下操作,但不起作用: private static HashMap<String, FileInfo> sFileInfoObjectList = new CacheLinkedHashMap<String, FileInfo>(); public static synchronized FileInfo getFileInfoForProvider(...) { Fi

我在run()方法中得到一个concurentModificationException。我尝试了以下操作,但不起作用:

private static HashMap<String, FileInfo> sFileInfoObjectList = new CacheLinkedHashMap<String, FileInfo>();

public static synchronized FileInfo getFileInfoForProvider(...) {
 FileInfo foundFileInfo = null;

 (...)

 foundFileInfo = sFileInfoObjectList.get(hashEntryKey);

 (...)

 sFileInfoObjectList.put(hashEntryKey, foundFileInfo);

 (...)
}

public static synchronized void removeFileInfoForProvider(final int providerId) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            Iterator<Entry<String, FileInfo>> it = sFileInfoObjectList.entrySet().iterator();
            while (it.hasNext()) {
                Entry<String, FileInfo> pair = it.next();
                FileInfo info = pair.getValue();
                if (providerId == info.mProvider) {                            
                    it.remove();
                }
            }
        }
    };
}
public void run(){
已同步(sFileInfoObjectList){
迭代器it=sFileInfoObjectList.entrySet().Iterator();
while(it.hasNext()){
条目对=it.next();
FileInfo=pair.getValue();
如果(providerId==info.mProvider){
it.remove();
}
}
}
}

您尚未同步
remove()
调用
映射。如果多个线程试图同时调用
run()
,它将抛出
ConcurrentModificationException
,这就是您案例中的原因

您可能需要使用synchronized on run()(或)使用并发集合,如
ConcurrentHashMap

run()不在同步块中,因为它在另一个线程上运行。您可以在run方法中使用synchronized,但使用引发此错误的并发集合要简单得多。例如,ConcurrentHashMap

顺便说一句:我不会每次都启动一个线程,因为它可能比在集合上迭代更昂贵。我会使用线程池,或者在当前线程中执行


用这个替换你的方法

public void run() {
    synchronized(sFileInfoObjectList) {
        Iterator<Entry<String, FileInfo>> it = sFileInfoObjectList.entrySet().iterator();
        while (it.hasNext()) {
            Entry<String, FileInfo> pair = it.next();
            FileInfo info = pair.getValue();
            if (providerId == info.mProvider) {                            
                it.remove();
            }
        }
    }
}
public static void removeFileInfoForProvider(final int providerId){
线程线程=新线程(){
@凌驾
公开募捐{
移除Provider0(providerId)的文件信息;
}
};
thread.start();
}
静态同步的void removeFileInfoForProvider0(最终int providerId){
迭代器it=sFileInfoObjectList.entrySet().Iterator();
while(it.hasNext()){
条目对=it.next();
FileInfo=pair.getValue();
如果(providerId==info.mProvider){
it.remove();
}
}
}

但是我使用的是LinkedHashMap,并且该方法是同步的。run()方法是在不同的线程中运行的,并且没有同步。已同步的方法不涉及集合,因此不需要对其进行同步。您必须锁定与本例中的类相同的对象(因为其他锁定是静态的)。更简单的方法是让它对类调用同步方法。顺便说一句,由于您的收藏是单线程的,因此启动另一个线程不会有多大帮助。我不知道,但您的所有评论都不是自我解释,也没有帮助,因为您似乎不理解给出的任何说明,也许你可以用上面的代码替换你的代码,这样就行了。我想OP认为让
removeFileInfoForProvider
同步就足够了。如果我在集合变量上同步,我就不需要同步remove()“如果我在集合变量上同步”是指使用并发集合吗?不,请参阅我写的第一篇文章:我尝试了以下方法,但没有成功:该方法应该可以正常工作,但问题可能是您正在对正在修改的对象进行同步,而这可能不起作用。使用其他方法来保持同步锁定。
public static void removeFileInfoForProvider(final int providerId) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            removeFileInfoForProvider0(providerId);
        }
    };
    thread.start();
}

static synchronized void removeFileInfoForProvider0(final int providerId) {
    Iterator<Entry<String, FileInfo>> it = sFileInfoObjectList.entrySet().iterator();
    while (it.hasNext()) {
        Entry<String, FileInfo> pair = it.next();
        FileInfo info = pair.getValue();
        if (providerId == info.mProvider) {                            
            it.remove();
        }
    }
}