So I have been trying to write a java program, that involves Threads. It is basically a problem where a thread asks a shared memory resource(cell class in the code below) for permission to move. I’ll show you an example of the code in the thread. The three mentioned methods from the cell class are synchronized methods, however they don’t implement wait or notify’s.
public void run() {
try{
while(true){
Random r = new Random();
Thread.sleep(r.nextInt(1000));
//asks the class cell permission to move if the cell is free.
if(cell.asksAccess(xi, yi, xf, yf)){
cell.releaseCell(xi, yi); //release the previous cell
move(); // move the object
cell.blockCell(xi, yi); // blocks the cell where the object is now staying.
setChanged();
notifyObservers();
}
}
} catch (InterruptedException e) {
}
}
private void move() {
int dx = xf - xi;
int dy = yf - yi;
xi += (int) Math.signum(dx);
yi += (int) Math.signum(dy);
}
Like I said before, all the cell class methods invoked are synchronized. My problem is that this is not working as I expected and when I did a sysout to debug, it showed that the threads are not always moving forward and sometimes they even move back to where they were in the beginning and I can’t understand why since the move method always tells them to go forward and never back. Is this a sync problem with the cell class? Or is it the move method? Any help would be a lot appreciated.
First, lets consider the
movemethod. Assuming that:xi,xf,yiandyfvariables are instance variables of theRunnable, andthen we can conclude that those variables are “thread confined” and no synchronization is required.
So where is the problem? Well I think it is here:
I can see two issues:
askCell,blockCellandreleaseCellsynchronize on thecellobject. But the problem is that the sequence “ask, block, release” needs to be atomic.xi, yi… and then blocking it again. The comments seem to imply that you should be callingcell.blockCell(xf, yf)instead.Without seeing the related code, it is hard to say what the best way is. But one way to do it would be to make it one call on the
cellobject … and deal with themoveand notifications afterwards; e.g. something like this:where
checkAndMoveis defined in theCellclass as: