2015-11-22 3 views
0

В каждом потоке я хочу запустить этот вид кода Инициализировать списокCopyOnWriteArrayList удалить логику

final int initialSize = 2000; 
     final Random rand = new Random(System.currentTimeMillis()); 
     Thread creationThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       for (int j = 0; j < initialSize; j++) { 
        list.add(rand.nextInt(10000)); 
       } 
      } 
     }); 
     creationThread.start(); 
     creationThread.join(); 
     List<Thread> threads = new ArrayList<Thread>(); 
     final int threadElemAmount = initialSize/numberOfThreads; 

Создание темы для удаления

for (int i = 0; i < numberOfThreads; i++) { 
     threads.add(new Thread(new Runnable() { 
      @Override 
      public void run() { 
       for (int j = 0; j < threadElemAmount; j++) { 
         list.remove((int) (list.size() - 1)); 
       } 
      } 
     })); 
    } 

, но я получаю ArrayIndexOutOfBoundsException проблему чтения-записи. Как избежать этого?

+0

Какая потребность в литье? – Rehman

+0

Почему вы используете цикл, но не используете переменную i? – Abdelhak

+0

@ Rehman hm, не мог понять вас. – jenius

ответ

0

Если вы просто хотите быть уверены, что ваша операция успешного удаления, затем синхронизировать свой код в списке, как:

public void run() { 
    for (int j = 0; j < threadElemAmount; j++) { 
     synchronized (list) { 
      list.remove((int) (list.size() - 1)); 
     } 
    } 
} 

успокаивать Кроме того, что вы синхронизации одного экземпляра списка.

Проблема вызвана тем, что эта линия:

list.remove((int) (list.size() - 1)); 

обрабатывается следующим образом:

1: int tempVal = list.size() - 1; 
2: list.remove(tempVal); 

В вашем случае, поток А выполнял линию 1, получая контекст выполнения для thread B, который выполнял 1 и 2, а затем поток A выбрасывал исключение.

+0

Не только это, JAVA API явно заявляет, что «если несколько потоков обращаются к экземпляру ArrayList одновременно, и по крайней мере один из потоков модифицирует список структурно, он должен быть синхронизирован извне». Http : //docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html Таким образом, даже если вы удаляете элемент в позиции 0, вы должны синхронизировать доступ к ArrayList. – Palo

+0

Спасибо, я знать об этом возможном решении, но есть ли только способ решить эту проблему? Потому что я уже использую thread-safe CopyOnWriteArrayList.java. Просто внешняя синхронизация? – jenius

+0

@Palo, вы прочитали название вопроса? Он использует 'CopyOnWriteArrayList' , который допускает одновременные изменения. – user3707125

Смежные вопросы