2016-03-03 42 views
-1

我已經定義了返回一個列表一個ExecutorService爲List<Callable> callables=Collections.synchronizedList(new ArrayList<Callable>());的ExecutorService和List <未來<Callable>>與ConcurrentModificationException的

我做了一個synchronizedList當我第一次過這個問題,因爲我認爲這將是線程安全的,但問題仍然存在。

我遇到的問題是,下面的代碼在低於Future<Object> next = i.next();拋出ConcurrentModificationException的。值得注意的是,它在爆炸前部分通過列表。

  ExecutorWorker snapshotExecutorWorker=new ExecutorWorker(this); 
     Iterator<Future<Object>> i= futures.iterator(); 
     while(i.hasNext()){ 
     Future<Object> next = i.next();//List<Callable> 
     try { 
      Object get = next.get(); 
      Class<? extends Object> aClass = get.getClass(); 
      System.out.println("Class= "+aClass); 
     List<Callable> l= (List)get; 
     System.out.println("L.size= "+l.size()); 
     for(int a=0;a<l.size();a++){     
     snapshotExecutorWorker.addTask(l.get(a)); 
     } 

     } catch (InterruptedException ex) { 
      Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (ExecutionException ex) { 
      Logger.getLogger(GUI.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     } 

ExecutorWorker基本上是一個SwingWorker,用於監視ExecutorCompletionService的狀態。

public class ExecutorWorker extends SwingWorker<List<Future>, Object> implements ExecutorInterface { 

List<Future> results = new ArrayList(); 
ExecutorService executorService = Executors.newFixedThreadPool(100); 
ExecutorCompletionService<Object> ecs = new ExecutorCompletionService<>(executorService); 
List<Future<Object>> jobs = new ArrayList(); 
ProgressMonitor progressMonitor; 
boolean isExecuting = true; 
Monitor monitor; 

public ExecutorWorker(Monitor f) { 
    monitor = f; 

} 

public void addMonitor(Monitor f) { 
    monitor = f; 
} 

/** 
*This method adds Callables to the Executor. 
* @param r 
* @return 
*/ 
@Override 
public Future<?> addTask(Callable r) { 
    Future futureValue = ecs.submit(r); 
    monitor.addFuture(futureValue); 
    System.out.println("Callable added in [ExecutorWorker]"); 
    jobs.add(futureValue); 
    monitor.tasksAdded(true); 
    return futureValue; 
} 

/** 
*This method returns a List containing the Future results. Use Future.get() to retrieve. 
* @return 
*/ 
public List<Future> getResults() { 
    return results; 
} 

@Override 
protected void done() { 

} 

@Override 
protected List<Future> doInBackground() throws ExecutionException, InterruptedException { 
//  System.out.println("Executor: In Do In BackGround"); 
//  System.out.println("Jobs.size= " + jobs.size()); 

    for (int i = 0; i < this.jobs.size(); i++) { 
     Future<Object> take = ecs.take(); 
     results.add(take); 
     monitor.tasksCompleted(true); 
     int v = (int) ((monitor.getCompletedTasks()/  this.monitor.getTotalTasks()) * 100); 
     this.setProgress(v); 
     String message = String.format("Processing " + (i + 1) + " of " +  jobs.size() + " Jobs. %d%%.\n", v); 
     System.out.println("Message= " + message); 
     progressMonitor.setNote(message); 


    } 

    return results; 

} 

public void setProgressMonitor(ProgressMonitor progressMonitor) { 
    this.progressMonitor = progressMonitor; 
} 
} 
+0

沒有時間進入它現在,但是你從哪裏獲得期貨收益?因爲你似乎正在改變那個集合,而你試圖迭代它,那麼...... welll ......你做不到。 – Mark

+0

你的第一塊代碼似乎與你的第二塊代碼無關。我懷疑第一個塊可能是Monitor類的addFuture方法,但我不想根據這種猜測來回答。請顯示第一個代碼塊所屬的方法和類。 – VGR

回答

0

Collections.synchronizedList()返回列表,只有方法同步,它不更新迭代器,所以ConcurrentModificationException的仍然是可能的。

0

如果在迭代迭代器時修改列表,則迭代器將失效並在下次使用迭代器時拋出ConcurrentModificationException異常(有關詳細信息,請參閱「迭代器的快速失敗屬性」)。

所有這一切保證讓synchronizedList確實是包裹每個呼叫到列表的以同步塊的方法。你不需要有多個線程來獲得ConcurrentModificationException,你只需要做一些破壞迭代器的事情。

我相信你的具體例子的問題是,addTask導致您迭代要修改的列表。

這個問題說明)使用iterator ::刪除(,它允許某些種類的藏品進行一些修改,而迭代他們,雖然這有點切到您的實際問題: Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop

+0

您是否認爲切換到for循環可以解決問題? –

+0

它與你正在使用的循環無關。 –

+1

哎呀,似乎「進入」發送消息:P。 問題是,如果迭代的集合被修改,則迭代器將變爲無效。當您嘗試使用以這種方式失效的迭代器時,它會引發ConcurrentModificationException。 要解決你的程序,你需要使它停止修改而迭代它的過程列表。一種方法可能是批量修改您想要執行的操作,然後在循環之後立即應用它們。 (有一個「要添加的東西」,你的循環填充的列表,然後你將所有這些東西添加到循環後的真實列表中)說) –

相關問題