ConditionVariable可防止两个线程同时运行

时间:2013-06-04 22:18:29

标签: java android multithreading condition-variable

我正在尝试在一对Android线程之间强制执行同步以进行游戏编程。我已经分配了一个处理大多数职责的游戏线程,以及一个渲染线程,它的任务是交换缓冲区和渲染。当我第一次询问线程同步时,我被引用到ConditionVariable对象作为强制线程阻塞直到并发任务完成的有用工具。

我的源代码如下所示:

            ...
            final ConditionVariable bufferLock = new ConditionVariable();
            final ConditionVariable cycleLock = new ConditionVariable();

            bufferLock.open();
            cycleLock.open();

            Runnable bufferSwapTask = new Runnable()
            {
                public void run()
                {
                    swapBuffers();
                    bufferLock.open();
                }
            };

            Runnable renderTask = new Runnable()
            {
                public void run()
                {
                    Log.d(TAG, "drawAll");
                    drawAll();
                    cycleLock.open();
                }
            };

            while(!halt)
            {
                if(!init)
                {
                    synchronized (userInputLock)
                    {
                        fetchUserInput();
                    }

                    processUserInput();
                    gameLogic();

                    bufferLock.block();
                    cycleLock.close();
                    renderThreadHandler.post(renderTask);
                    recycleDisplayObjects();
                    enqueueDisplayTree();

                    cycleLock.block();
                    bufferLock.close();
                    renderThreadHandler.post(bufferSwapTask);
                }
            }
            ...

所以事情按照正确的顺序执行,但没有达到我预期的性能水平。而且,当我激活DDMS方法跟踪时,我发现DVM实际上会中断并阻塞每个线程以允许其他线程恢复,以强烈暗示两个线程仅由一个CPU处理的方式来回切换。

我使用ReentrantLocks获得了很好的同步处理结果,那么为什么ConditionVariable会产生这种影响呢?

1 个答案:

答案 0 :(得分:2)

Android上的Linux内核试图避免在核心之间移动线程。如果一个线程是“可运行的”(即可以运行但正在等待另一个线程)一段时间,内核可以决定将其迁移到另一个核心。

如果在之前的实现中,您的某个线程倾向于连续运行,则可能会使另一个线程保持“runnable”足够长的时间以使内核迁移它。新的实施可能会以较小的步骤移动并低于阈值。

FWIW,其他人对此感到困惑,例如: herehere