4

我正在阅读一些用于学习目的的 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 对象访问画布,然后在绘制画布时锁定该对象。为什么需要同步?

我认为不是,因为唯一请求画布并在其上绘图的线程是游戏循环运行的线程。

SurfaceHolder.lockCanvas() 的文档还说它会获取内部锁,直到调用 unlockCanvasAndPost(),那么为什么要额外同步?

4

2 回答 2

1

查看源代码的其余部分,SurfaceView 线程之外的许多其他操作也同步在mSurfaceHolder. 因此,我的信念是,mSurfaceHolder它被用作方便的“锁定”对象,以在线程和应用程序的其余部分之间同步状态。

于 2013-09-23T15:01:54.777 回答
1

如果您查看您提供的参考资料,完整的报价是:

如果未返回 null,则此函数在内部保持锁定,直到相应的 unlockCanvasAndPost(Canvas) 调用,防止 SurfaceView 在绘制时创建、销毁或修改表面

我的重点 - 请注意,阅读不在列表中。

所以lockCanvas不会阻止它被读取。我猜想额外的同步是为了确保其他线程当时没有从中读取 - 这是有道理的,因为您正在调用updatePhysics这可能会让其他读者感到不安。

于 2013-09-23T14:52:05.240 回答