我正在(尝试)编写一个小游戏。我的设计/死锁问题很小。
当我按下一个按钮时,一个新的Intent打开,surfaceDestroyed设置一个布尔值来设置线程休眠。 当我返回时,线程获得通知信号。
大约90%的时间都可以使用(当我使用eclipse进行调试时,这是100%)。
我相信死锁发生在线程的run函数中(两个已同步)。问题是,wait()需要一个同步的线程,而ondraw()需要锁定在surfaceholder上。
我已经玩了一下,但所有其他组合使一切变得更糟,我不知道如何解决这个问题。所以请帮助:))
线程:
class BattleEarthThread extends Thread {
private SurfaceHolder _surfaceHolder;
private BattleEarthView _battleEarthView;
private boolean _run = false;
private boolean _suspended = false;
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
public BattleEarthThread(SurfaceHolder surfaceHolder, BattleEarthView panel) {
_surfaceHolder = surfaceHolder;
_battleEarthView = panel;
}
public void setRunning(boolean run) {
_run = run;
}
public void setSuspend(boolean suspend) {
_suspended = suspend;
}
public boolean getSuspended() {
return _run;
}
public boolean getRunning() {
return _run;
}
@Override
public void start() {
super.start();
_run = true;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
synchronized(this)
{
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
if(_suspended)
this.wait();
else {
_battleEarthView.onDraw(c);
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
答案 0 :(得分:3)
这是问题所在:
synchronized(this) {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
if(_suspended)
this.wait();
else {
_battleEarthView.onDraw(c);
}
}
}
你正在取出两把锁 - this
和_surfaceHolder
。然后,您通过调用this
释放锁定wait
...但您仍拥有_surfaceHolder
的锁定。
现在假设另一个线程在同一个对象上执行相同的代码。它设法获取this
的锁,因为此刻没有其他任何东西......但它在尝试获取_surfaceHolder
时会阻塞,因为等待的线程拥有它。
此时,你被塞满了:
this
上的锁定,这将无法所以基本上你有两个线程,每个线程拥有一个锁,正等待一些不可能发生的事情。它不是相当正常的死锁(每个线程拥有一个锁并等待另一个锁)但它非常接近。
道德:不要在当前“拥有”更多监视器的线程上调用wait()
,而不是要调用wait()
的监视器。