0
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(); 
       } 
      } 
     } 
    }; 
} 

我在run()方法中得到一個ConccurentModificationException異常。我嘗試以下,並沒有奏效:ConcurrencyException

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(); 
      } 
     } 
    } 
} 

回答

2

運行()不是一個synchronized塊,因爲它是另一個線程上運行。你可以在你的run方法中使用synchronized,但是使用併發的集合會引起這個錯誤會更簡單。例如。 ConcurrentHashMap的。

順便說一句:我不會每次啓動一個線程,因爲它可能比迭代集合更昂貴。我會使用線程池,或者在當前線程中執行它。


與此

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(); 
     } 
    } 
} 
+0

但我正在使用LinkedHashMap並且該方法已同步 – David

+0

run()方法在不同的線程中運行,並且未同步。您已同步的方法不會觸摸集合,因此不需要同步。 –

+0

我嘗試使用run()後同步塊(){ – David

0

您還沒有同步remove()呼籲Map。如果多個線程同時嘗試撥打run(),它將拋出ConcurrentModificationException這是您的情況的原因。

您可能需要使用或者在運行同步()(或)使用併發收集像ConcurrentHashMap

+0

更換你的方法我承擔OP認爲做'removeFileInfoForProvider'同步就夠了。 –

+0

@PeterLawrey:我想是的。 – kosa

+0

如果我通過收集變量同步,我不需要同步刪除() – David