我正在阅读一些用于学习目的的基本Android游戏技术.
我遇到了一些同步访问游戏循环线程上使用的SurfaceHolder对象的代码,为什么这是必要的?
在sdk / samples / android-18 / legacy / LunarLander,LunarView.LunarThread类中找到示例代码:
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING) updatePhysics();
synchronized (mRunLock) {
if (mRun) doDraw(c);
}
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
因此,这段代码可以从mSurfaceHolder对象访问画布,然后在绘制画布时锁定该对象.
为什么需要同步?
我认为不是,因为请求画布和绘图的唯一线程是游戏循环运行的线程.
另外the documnetation of SurfaceHolder.lockCanvas()说它将获取一个内部锁,直到调用unlockCanvasAndPost(),然后为什么额外同步?
解决方法:
如果你查看你给出的参考,完整的报价是:
If null is not returned, this function internally holds a lock until the corresponding unlockCanvasAndPost(Canvas) call, preventing SurfaceView from creating, destroying, or modifying the surface while it is being drawn.
我的重点 – 请注意,阅读不在列表中.
所以lockCanvas不会阻止它被读取.我猜想额外的同步是为了确保其他线程当时不会从中读取 – 这是有道理的,因为你正在调用updatePhysics,这可能会让其他读者感到不安.