2013-07-06 2 views
1

Я использую ExecutorService для процесса multiThread - у меня есть список идентификаторов, для каждого ID я делаю часть кода с помощью потоков.ConcurrentModificationException при попытке выполнить MultiThread в партиях

ExecutorService executor = Executors.newFixedThreadPool(4); 
for (String id : listOfIDs) { 
    Runnable worker = new WorkerThread(id); 
    executor.execute(worker); 
} 
executor.shutdown(); 
.... 

Все работает нормально, и результаты ожидаются. Но поскольку у меня много идентификаторов, мне нужно сделать эту часть более эффективной. У меня проблема с производительностью, и кажется, что это связано с созданием Lof WorkerThreads. Я решил запустить его для списка baseIds, а позже в запустил метод в WorkerThread (или в другом методе, называемом оттуда), через список по потоку. Но у меня проблема с java.util.ConcurrentModificationException. Что я делаю не так?

for (String id : listOfIDs) { 
    listForThreads.add(id); 
    if (listForThreads.size() >= 100) { 
    Runnable worker = new WorkerThread(listForThreads); 
    executor.execute(worker); 
    listForThreads.clear(); 
    } 
} 
.... 
public static class WorkerThread implements Runnable { 

    private List<String> listForThreads; 
    public WorkerThread (List<String> listForThreads) { 
     this.listForThreads = listForThreads; 
    } 
public void run() { 
    for (String id : listForThreads) { 
    process(id); 
} 
} .... 

Я думал, что обработаю больше идентификаторов только в одном потоке, а не в потоке. Можно ли использовать ExecutorService для запуска некоторых процессов в «партиях»?

+0

Вы можете показать код для метода процесса? [ConcurrentModificationException] (http://docs.oracle.com/javase/6/docs/api/java/util/ConcurrentModificationException.html) происходит при модификации (добавлении/удалении элементов) коллекции, в то же время итерации над ним. – linski

ответ

0

Ваш код здесь не так в этом разделе

for (String id : listOfIDs) { 
    listForThreads.add(id); 
    if (listForThreads.size() >= 100) { 
    Runnable worker = new WorkerThread(listForThreads); 
    executor.execute(worker); 
    listForThreads.clear(); 
    } 
} 

Вы не должны вносить изменения в то время как итерация список. Здесь вы делитесь тем же экземпляром списка с рабочими потоками. Которые повторяются в одном экземпляре списка, и вы очищаете список одновременно (в то же время) в основном потоке. Идеально Вы должны создать копию ArrayList при совместном использовании с другими потоками, которые работают только для чтения. Создать копию ArrayList с помощью ** listForThreads.toArray (новый String [listForThreads.size()]) ** или клонирования данного списка см ответа на этот вопрос Java ArrayList copy

+0

работает отлично! благодаря! – user2557110