views:

82

answers:

3

Ive create a game and the portion of the program I am having a problem is modeled with a slightly modified MVC model.

For the controller I use a TimerTask to run 60 times a second.

Controller(){
    timer = new Timer();//
    timer.schedule(tt,1000,1000/60);
}
TimerTask tt = new TimerTask() {//Controller member variable
    public void run() {
        timerUpdate();
    }
};

timerUpdate(){
model.advanceGameLogic(); //Tells the model to increment a tick
    if(model.isPlay()){
        checkRowCount();//Logic to check if any rows have been removed
        view.repaint(); //Tells model to repaint itself
        updateNextShape(); //Tells class to poll model for new shape
        }
}

All this seems fine to me but later inside model, from the advance gameLogic code, I try and update an array comprising the gameState.

Using logging before and after calls of colorArr[row][col] = s.getColor(); I am able to observe that multiple values in this array are being changed from this one call at once.

Have I used timers in an incorrect way so as to make the game logic inconsistent or are there other conditions that can result in my problem? I can update the code or post more about what calls are made to get to the array change if that will help.

A: 

I can't clearly tell if it's a problem in your usage if timer task, but according to Brian Goetz's best practices provided in Java Concurrency in Practice (Chapter 6.2.5) you should regard ScheduledThreadPoolExecutor as a replacement and successor to Timer/TimerTask as they behave poorly when Exceptions occur inside the task.

Johannes Wachter
Using ScheduledThreadPoolExecutor didn't work. I changed my TimerTask to a runnable and replaced timer with ScheduledThreadPoolExecutor. I then used scheduleWithFixedDelay() to schedule the runnable. My problem still happened. Does this point away from concurrency?
maleki
I would suppose that your methods are not synchronized correctly. You should check if all methods are using thread-safe access and modification on the stored state. this means all related state has to be guarded by the same lock/monitor. This would kind of explain inconsistent values, since multiple threads could change state in an unsafe manner.
Johannes Wachter
Is there a way to synchronize the TimerTask so that it wont call timerUpdate if there is another already going instead of making trying to synchronize all through the model.
maleki
A: 

While java.util.Timer is thread safe, view.repaint() may not be. If you are using Swing, javax.swing.Timer may be a useful alternative, as the event handler executes on the event-dispatching thread (EDT).

Addendum:

...multiple values in this array are being changed from this one call at once.

The problem you describe sounds like a data race, so I'm guessing that your model and view execute on different threads. In Swing, painting on the EDT is a necessary, but not sufficient, condition. You still have to synchronize access to ensure visibility of data shared by the view and model. You might look at some of the approaches discussed here.

trashgod
Threw in an Actionlistener and changed it to javax.swing.Timer. No luck..
maleki
@maleki: By itself, that may not suffice; I've elaborated above.
trashgod
A: 

Simply put..No. In this instance it was fine.

I solved the problem. It was introduced due to the way I was setting an array. It ended up looking like a concurrency problem to me due to the method causing the bug not seeming connected to where it was showing up.

See the following for how I created the bug and fixed it. http://stackoverflow.com/questions/3545049/why-does-changing-an-entire-array-row-create-odd-behavior

maleki
So, are you saying that you resolved the issue?
jjnguy