所以我一直在尝试编写一个涉及Threads的java程序。它基本上是一个问题,其中一个线程要求共享内存资源(下面代码中的单元类)的移动权限。我将向您展示线程中代码的示例。来自单元类的三个提到的方法是同步方法,但它们不实现wait或notify。
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);
}
就像我之前说的那样,调用的所有单元类方法都是同步的。我的问题是这没有按照我的预期工作,当我做一个sysout调试时,它表明线程并不总是向前移动,有时它们甚至会回到原来的位置,我无法理解为什么因为移动方法总是告诉他们前进而永远不会回来。这是细胞类的同步问题吗?或者是移动方法?任何帮助都会受到很多赞赏。
答案 0 :(得分:0)
私有void move()方法应该同步。
答案 1 :(得分:0)
首先,让我们考虑一下move
方法。假设:
xi
,xf
,yi
和yf
变量是Runnable
的实例变量,然后我们可以得出结论,这些变量是“线程限制的”,并且不需要同步。
问题出在哪里?我认为它就在这里:
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();
}
我可以看到两个问题:
askCell
,blockCell
和releaseCell
在cell
对象上同步。但问题是“询问,阻止,释放”序列需要是原子的。xi, yi
释放一个单元格(?)然后再次阻止它。这些评论似乎暗示您应该拨打cell.blockCell(xf, yf)
。...处理该序列同步的最佳方法是什么?
如果没有看到相关代码,很难说最好的方法是什么。但一种方式是在cell
对象上进行一次调用...然后处理move
和通知;例如像这样的东西:
if (cell.checkAndMove(xi, yi, xf, yf)) {
move(); // move the object
setChanged();
notifyObservers();
}
其中checkAndMove
在Cell
类中定义为:
public synchronized boolean checkAndMove(int xi, int yi, int xf, int yf) {
boolean ok = this.asksAccess(xi, yi, xf, yf);
if (ok) {
this.releaseCell(xi, yi);
this.blockCell(xi, yi);
}
return ok;
}