Syncing in the Android game loop


I'm reading about some android basic game techniques for learning purposes.

I came across some code that synchronizes the access to the SurfaceHolder object used on the game loop thread, why is this necessary?

Sample code found in sdk/samples/android-18/legacy/LunarLander, LunarView.LunarThread class:

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) {

So this piece of code gets access to the canvas from the mSurfaceHolder object, which is then locked while the canvas is being drawn on. Why is the synchronization necessary?

I think it's not, since the only thread requesting the canvas and drawing on it is the thread where the game loop runs.

Also the documnetation of SurfaceHolder.lockCanvas() says that it will aquire an internal lock until the unlockCanvasAndPost() is called, then why the extra synchronization?

If you look at the reference you gave, the full quote is:

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.

My emphasis - note that reading is not in the list.

So lockCanvas does not stop it being read from. I would guess the extra synchronization is intended to ensure that other threads are not reading from it at the time - which makes sense because you are calling updatePhysics which could be rather upsetting for other readers.