Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm programming a simple Snake in Java. I'm a complete newbie when it comes to Java and Game Developing, so please bear with me ;)

Until now, I have been using a UI thread, as well as a update-thread. The update thread just set the position, set the GameObjects, and so on.

I didn't think much of concurrency, but now I've come to a problem.

I wanted to modify the ArrayList<GameObject>, but it throws a java.util.ConcurrentModificationException.

With a little research I found out that this happens because the two threads are trying to access the variables at the same time.

But I didn't really find a way to prevent this. I thought about copying the array and swapping them out when the rendering is finished, but I would have to deep-copy them, which isn't really the best solution in my opinion. It probably eats up more CPU resources than a single-threaded game.

Are there any other ways to prevent this?

Thanks a lot for your help!

share|improve this question
1  
Why do you use threads? –  Liosan Nov 23 '12 at 12:45
    
@Liosan 1. So the game loop doesn't block the ui thread. 2. For practise. –  NSAddict Nov 23 '12 at 12:46
    
Have you tried making your Collection thread safe? One way to achieve this is using the synchronizedCollection method. –  Asakeron Nov 23 '12 at 14:25
1  
A thread safe Collection isn't going to make a thread safe program. Even with a synchronized collection, you will still be rendering the world in an inconsistent state. Either guard the entire update operation with a mutex, or better yet, don't use multi-threading without proper motivation. If your rendering takes so long as to lock up your UI, you have a bigger problem :) If your game updates take too long, consider splitting the work into smaller pieces and spread them out over several frames. –  ccxvii Nov 23 '12 at 17:24

1 Answer 1

up vote 4 down vote accepted

Use wait and notify to ensure that only one of your threads is modifying the object at a time. You'll need a class to hold your ArrayList:

class GameObjectManager {
    private ArrayList<GameObject> objects;
    private Boolean rendering = false;

    public GameObjectManager(){
        //Initialize objects
    }

    public synchronized void update() {
        if (rendering)
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException caught");
            }

        // update objects...

        rendering = true;
        notify();
    }

    public synchronized void render() {
        if (!rendering)
            try {
                wait();
            } catch (InterruptedException e) {
                System.out.println("InterruptedException caught");
            }

        // render objects...

        rendering = false;
        notify();
    }
}

The Update thread might look something like this:

class UpdateThread implements Runnable {
    private GameObjectManager manager;

    public UpdateThread(GameObjectManager m) {
        this.manager = m;
        new Thread(this, "Update").start();
    }

    public void run() {
        while (true) {
            m.update();
        }
    }
}

The Render thread would follow suit:

class RenderThread implements Runnable {
    private GameObjectManager manager;

    public RenderThread(GameObjectManager m) {
        this.manager = m;
        new Thread(this, "Render").start();
    }

    public void run() {
        while (true) {
            m.render();
        }
    }
}

Now the main function that controls it all would do something resembling this:

public static void main(String args[]) {
    GameObjectManager manager = new GameObjectManager();
    new UpdateThread(manager);
    new RenderThread(manager);
    System.out.println("The game is running now...");
}

So here's what happens:
1. The main function creates two threads, the update and render threads.
2. Both threads try to do their task, but the GameObjectManager forces the render thread to wait() until the update thread has called notify().
3. The update thread finishes updating, notifies the render thread, and then waits.
4. The render thread finishes rendering, notifies the update thread, and then waits.

And so on.

share|improve this answer
    
How is this an improvement over just using a single thread? –  ccxvii Nov 23 '12 at 16:56
    
Just wanted to ask this, I loose the advantages of multithreading with this... –  NSAddict Nov 23 '12 at 17:34
    
Updating and Rendering have to happen in sequence, there are no advantages to multithreading them at all. This is just a way to sequence them if you have threads in place already. –  Eric B Nov 23 '12 at 18:14
    
@NSAddict If this removes all the advantages of multi-threading then you're not threading the right parts of your code. Eric has given you a correct answer that solves your concurrent modification issues. Deciding what code to thread is a different problem. –  Byte56 Nov 23 '12 at 18:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.