java swing параллельный экранный текст в JTextArea с циклом - PullRequest
0 голосов
/ 16 декабря 2010

Мне нужно выполнить / отобразить серию событий от Arraylist до JTextArea, однако каждое событие выполняется с разным временем. Ниже приведен код, который завершается с ошибкой во время второго события в цикле:

   Thread worker = new Thread(new Runnable()
            {
                public void run()
                {
                    while (eventList.size() > 0)
                        for (Event ev : eventList)
                        if(ev.ready())
                        {
                            /*try
                            {
                                Thread.sleep(1000);
                            } catch (InterruptedException e1)
                            {
                                e1.printStackTrace();
                            }*/
                            jTextArea.append(ev.toString() + "\n");
                            eventList.remove(ev);

                        }
                }
            });
            worker.start();

Ответы [ 2 ]

7 голосов
/ 16 декабря 2010

Я думаю, у вас есть ConcurrentModificationException. Попробуйте использовать итератор, что-то вроде этого:

Iterator<Event> it = eventList.iterator();
while(it.hasNext())
{
  Event ev = it.next();
  if (ev.ready())
    it.remove();
}

Редактировать Почему он выбрасывает исключение ConcurrentModificationException?

Если вы перебираете коллекцию, используя Iterator напрямую или for(E : list), и , вы изменяете коллекцию, вызывая add, remove или подобное, вы получите это исключение. Это пытается указать, что есть проблема в коде. Проблема в том, что один фрагмент кода хочет перебрать все объекты, в то время как другой фрагмент добавляет или удаляет объекты. Первый кусок кода попадает в неприятности, как он может зацикливаться на всем, если коллекция продолжает изменяться? Таким образом, «они» решили, что вы не можете изменять коллекцию, когда вы зацикливаетесь на ней. (Если вы не измените его с помощью итератора, который вы используете для цикла, как это делает этот код. it.remove(), it является итератором цикла и, следовательно, не дает сбоя.) Надеюсь, что это имеет смысл.

2 голосов
/ 16 декабря 2010

Я могу повторить то, что сказал Лштар, но я добавлю кое-что свое. На самом деле я взял это из книги "J2EE Interview Companion".

Классы java.util Collection работают быстро, что означает, что если один поток изменяет коллекцию, в то время как другой поток просматривает ее с помощью итератора, то iterator.hasNext () или итератор .next () вызов вызовет ConcurrentModificationException . Даже классы-оболочки синхронизированных коллекций SynchronizedMap и SynchronizedList являются только условно поточно-ориентированными, что означает, что все отдельные операции являются поточно-ориентированными, но составными Операции, в которых поток управления зависит от результатов предыдущих операций, могут вызывать проблемы с многопоточностью.

Решение:

Используйте ConcurrentHashMap или CopyOnWriteArrayList ( java.util.concurrent пакет). Их итераторы обеспечивают лучшую масштабируемость.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...