运行两个线程

时间:2015-06-04 04:21:23

标签: java multithreading arraylist concurrency network-programming

所以,我目前正在开发一个支持多客户端的服务器,我有一个线程检查是否有任何套接字连接到给定端口,然后将它们添加到另一个线程用来更新所有内容的arraylist需要使用客户端(更新信息,检查DataInputStream,通过服务器发送文本)等。

客户代码:

public class Loop implements Runnable{

ArrayList<ClientInstance> clientsConnected = new ArrayList<ClientInstance>();

@Override
public void run() {
    while(true) {
        checkInputStream();
    }

}

public void checkInputStream() {
    for (ClientInstance s : clientsConnected) {
        s.checkInputStream();
    }
}

服务器代码:

public synchronized void waitForClient() {
    try {
        System.out.println("Waiting for client on port: "
                + serverSocket.getLocalPort());
        Socket client = serverSocket.accept();
        System.out.println("Client Connected! " + client.getInetAddress());
        loop.getClientsConnected().add(new ClientInstance(client));
        System.out.println("Client added to clients connected! ");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

但是,当我运行服务器然后将一个客户端连接到它时,它工作正常,但当我连接另一个客户端时,它给了我这个问题:

Exception in thread "Thread-1" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)

我该怎么办?

3 个答案:

答案 0 :(得分:1)

这是因为您正在修改arraylist(即在waitForClient()方法中添加列表中的元素),同时您正在checkInputStream()方法中进行迭代。

如@Arjit所述,使用CopyOnWriteArrayList代替ArrayList

答案 1 :(得分:1)

使用CopyOnWriteArrayList进行修复

List<String> myList = new CopyOnWriteArrayList<String>();     
myList.add("1");
myList.add("2");
myList.add("3");myList.add("4");myList.add("5");
System.out.println("List Value:"+value);

        Iterator<String> it = myList.iterator();
        while(it.hasNext()){
            String value = it.next();                    

            if(value.equals("3")){
                myList.remove("4");
                myList.add("6");
                myList.add("7");
            }
        }
        System.out.println("List Size:"+myList.size());

输出: -

List Value:1
List Value:2
List Value:3
List Value:4
List Value:5
List Size:6

PS: -

  1. 可以修改并发集合类,避免使用ConcurrentModificationException

  2. 如果是CopyOnWriteArrayList,迭代器不能容纳列表中的更改并在原始列表中工作。

答案 2 :(得分:0)

虽然你为方法waitForClient进行了同步(你在这里插入元素)但你没有锁定方法checkInputStream

您可以使用CopyOnWriteArrayList代替ArrayList。它已在问题"Avoiding a possible concurrency issue with a LIST being returned"

中得到解答