ConcurrentModificationException при отправке сообщения всем клиентам

У меня проблема при повторении ArrayList of Sockets. Цель списка - отправить сообщение всем клиентам, когда подключается другой, кроме последнего. Я получаю ConcurrentModificationException и не знаю, как с ним справиться. Пожалуйста помоги!

Серверная программа:

 public void start() {

    try {
        serverSocket = new ServerSocket(10001);
        thread = new Thread(new MessageClient(listOfClients));
        thread.start();
        while (!isStopped) {
        socket = serverSocket.accept();
        listOfClients.add(socket);
        synchronized (listOfClients) {
            listOfClients.notifyAll();
        }
        g.getTextArea().append(
            "Client number " + listOfClients.size()
                + " has connected.\n");
        threadClient = new Thread(new SerThread(socket, listOfClients));
        threadClient.start();
        }
    } catch (IOException e) {
    }
    }

Программа потока (MessageClient):

public void run() {
    while (true) {
        for (Iterator<Socket> cl = listOfClients.iterator(); cl.hasNext();) {
        synchronized (listOfClients) {
            cur = cl.next();
            if (!cur.equals(listOfClients.get(listOfClients.size() - 1))) {
            try {
                System.out.println("dddddddd");
                ous = new PrintWriter(cur.getOutputStream());
                ous.println("Client " + listOfClients.size()
                    + " has connected.");
                ous.flush();
            } catch (IOException e) {
                JOptionPane
                    .showMessageDialog(null,
                        "There was a problem getting your outputstream.");
            }
            try {
                System.out.println("ddd");
                listOfClients.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            }
        }
        }
    }
    }

person Hristo Yordanov    schedule 02.12.2014    source источник
comment
вставьте трассировку стека. Обычно вы получаете ConcurrentModificationException, когда пытаетесь изменить отказоустойчивую коллекцию во время ее итерации. Проверьте, где вы, возможно, делаете это, намеренно или нет.   -  person Nazgul    schedule 02.12.2014
comment
@Nazgul dddddddd ddd Исключение в потоке Thread-0 java.util.ConcurrentModificationException в java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886) в java.util.ArrayList$Itr.next(ArrayList.java:836) в com.omisoft.basic_java.networking_and_gui.task4.MessageClient.run(MessageClient.java:24) в java.lang.Thread.run(Thread.java:745) Это трассировка стека.   -  person Hristo Yordanov    schedule 02.12.2014


Ответы (2)


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

person Hristo Yordanov    schedule 05.12.2014

Вы пытаетесь изменить свою коллекцию listOfClients.add(socket) в одном потоке (на сервере), в то время как другой поток MessageClient перебирает ее.

person Tkachuk_Evgen    schedule 02.12.2014
comment
Не могли бы вы помочь мне с каким-то решением, пожалуйста? Спасибо за ответ в любом случае! - person Hristo Yordanov; 02.12.2014
comment
Заполните свой listOfClients, прежде чем начинать свой поток с MessageClient - person Tkachuk_Evgen; 02.12.2014
comment
Как я могу заполнить его, если клиенты могут подключаться в любое время? - person Hristo Yordanov; 02.12.2014
comment
Если вы хотите отправлять информацию только для последнего добавленного клиента, передайте объект Socket в свой Runnable вместо listOfClients, а затем используйте PrintWriter - person Tkachuk_Evgen; 02.12.2014