0

I am developing a multi-player snake game played over the network. It is running fine however it occasionally throws java.util.ConcurrentModification Exception. This is thrown in the main class of my game in the paintComponent() method. Code at which this is thrown is

 for (String name : map.keySet()) {
        if (!map.get(name).gameover) {
            for (int i = 0; i < map.get(name).length; i++) {
                rect = new Rectangle2D.Double(map.get(name).p[i].x,
                        map.get(name).p[i].y, width, width);
                g1.setColor(Color.black);
                g1.draw(rect);
                g1.setPaint(map.get(name).snakecolor);
                g1.fill(rect);
            }
        }
    }

The Hashmap map is a mapping from

        HashMap<String,Snake> 

where Snake is the class which has all the attributes of a snake. The main class also runs a thread side by side for receiving messages and updates from other clients through the server.

The iterator on the thread side also uses the same map(passed by reference to that class). Code for that is as given below. This function is called if the score of any player reaches some specific point after which the level is upgraded.

    void levelUp(int level){
    for(String name:map.keySet()){
        map.get(name).level=level;
    }
    Game.speed=100/level;
}

I think the clash between object write is due to this. Can anyone please suggest a solution for this problem.

The Code where I put values into the map is also given below.

void populateMap() {
    try {
        try {
            objin = new ObjectInputStream(socket.getInputStream());
        } catch (StreamCorruptedException e) {
            System.out.println("Stream Corrupted!");
        }
        Object name = objin.readObject();
        if (((Snake) name).player.equals("food_coord")) {
            Game.foodx = objin.readInt();
            Game.foody = objin.readInt() + 35;
            start = true;
            System.out.println("Game Started");
            return;
        } else {
            map.put(((Snake) name).player, (Snake) name);
            System.out.println("Recieved: " + ((Snake) name).player);
        }
    } catch (java.net.SocketException s) {
        JOptionPane.showMessageDialog(null, "Server Closed", "ERROR",
                JOptionPane.ERROR_MESSAGE);
        System.exit(0);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
5
  • using entrySet() in place of keySet() will optimize your code. Commented Apr 13, 2013 at 8:52
  • Where is map changed (put or remove called)? Commented Apr 13, 2013 at 8:53
  • That is at the initiation of the thread I will post that code above. Although in this case that part is not taking in concurrency since the paintComponent runs only after initiation has been completed Commented Apr 13, 2013 at 9:22
  • Chances are this populateMap() is being called when map is being iterated (that's the most common cause of ConcurrentModificationException). Can you also post the exception stacktrace? (And point which line is the last line executed.) Will help a lot. Commented Apr 13, 2013 at 9:46
  • When the populateMap() is done then no iterations on the map are done. A variable recievedfrom the server side triggers populateMap to be stopped and map iterations (that receive and update data) to begin. SO I dont think theres a clash there. Commented Apr 13, 2013 at 9:56

1 Answer 1

1

Change your map implementation class to one that support concurrency such as ConcurrentHashMap

Sign up to request clarification or add additional context in comments.

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.