2014-12-02 5 views
-3

У меня есть этот код:CopyOnWriteArrayList странная ошибка

int rnd1=Rnd.get(players.size()); 
int rnd2=Rnd.get(players.size()); 

while(rnd2==rnd1) 
    rnd2=Rnd.get(players.size()); 


for(L2PcInstance player : players) 
{ 
    if(player != players.get(rnd1) && player != players.get(rnd2)) 
      players.remove(player); 
} 

И у меня есть эта ошибка:

Exception in thread "GeneralSTPool-8" java.lang.ArrayIndexOutOfBoundsException: 2 at java.util.concurrent.CopyOnWriteArrayList.get(Unknown Source) at java.util.concurrent.CopyOnWriteArrayList.get(Unknown Source) at net.sf.l2j.gameserver.model.RandomFight.pickPlayers(RandomFight.java:89) at net.sf.l2j.gameserver.model.RandomFight$pickPlayers.run(RandomFight.java:270) at net.sf.l2j.gameserver.ThreadPoolManager$RunnableWrapper.run(ThreadPoolManager.java:85) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Что здесь происходит? Строка 89 такова: for(L2PcInstance player : players). Это не должно происходить с rnd.get() от 0 до players.size() - 1.

+0

Этот список больше не совпадает с указанным вами после удаления элементов. – kiheru

+0

@kiheru это список COW, хотя это не должно быть – fge

+0

@fge COW все еще может генерировать исключения при доступе к индексам за пределами границ. Это не исключение ConcurrentModification – kiheru

ответ

0

Цель состоит в том, чтобы удалить всех, кроме двух выбранных игроков из списка. Есть более простые способы сделать это. Например:

players.retainAll(Arrays.asList(players.get(rnd1), players.get(rnd2)); 

Это также не имеет проблем с параллельными изменениями, в случае, если была причина использовать CopyOnWriteArrayList.

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