当wait()不可用时,节省CPU

时间:2012-12-09 16:32:36

标签: java android multithreading wait

我的组件集成到第三方组件。我必须覆盖由第三方组件的高优先级onTick()调用的Thread方法。示例代码:

@Override
public void onTick() {

    // do many useful operations

}

在某些情况下,此onTick()方法不应执行那些“许多有用的操作”,因为它们的结果将被丢弃。实际上,在这种情况下根本不需要onTick()的功能,但第三方组件不提供任何“暂停”或“休眠”功能。它始终调用onTick() 。这意味着在这些特殊时期内CPU时间不必要地耗尽。

最直接的解决方案是向onTick()发送信号,并通过Object.wait()块中的synchronized使其线程休眠。但是,第三方组件的文档声明其Thread不应随意发送到等待状态。

在这种情况下,有没有解决方案来节省CPU资源?也就是说,让其他人使用CPU?我创建了以下解决方案,但我不确定它是否允许保存任何CPU。 (尽管如此,至少,它应该保存onTick()的“有用操作”部分使用的其他资源。

@Override
public void onTick() {

        // mJustUnpaused is volatile. Race condition, but probably harmless (?)
        if (mJustUnpaused) { 
            mJustUnpaused = false;
            // THREAD_PRIORITY_DISPLAY is the original 
            // priority used by the 3rd party Thread
            Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
        }

        if (!mRunningAllowed) {
            return;
        }

        if (mPauseRequested) { // mPauseRequested is declared as volatile
            synchronized (mPauseLock) {                 
                if (mRunningAllowed && mPauseRequested) {                       
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    mRunningAllowed = false;
                    mPauseLock.notify();
                }
            }               
            return;
        }

        // do many useful operations
}

暂停/取消暂停的方法(第一个是阻止,第二个不是):

public void pauseWork() {
    synchronized (mPauseLock) {
        if (mRunningAllowed && !mPauseRequested) {
            mPauseRequested = true;
            while (mRunningAllowed) {
                try {
                    mPauseLock.wait();
                } catch (InterruptedException e) {}
            }
        } else {
            Log.d("RPT", "Already paused or pausing");
        }
    }
}

public void unpauseWork() {
    synchronized (mPauseLock) {
        if (!mRunningAllowed) {
            mRunningAllowed = true;
            mPauseRequested = false;
            mJustUnpaused = true;
        } else {
            Log.d("RPT", "No need to unpause");
        }
    }
}

三个问题:

  1. 有没有更好的方法来节省一些CPU时间?
  2. 无论其他什么,我的上述代码是否正确(在同步和其他编程方面)?
  3. 稍微偏离主题,但我认为它不值得一个专门的问题:更改线程的优先级是否有任何重大开销?在做出这样的行为时,是否有任何一般性指导原则? (例如,多久可以完成等等)

1 个答案:

答案 0 :(得分:2)

  

有没有更好的方法来节省一些CPU时间?

我甚至不打扰那里的东西。我同意Chris Stratton:只是避免做实际工作,并删除上面显示的其他代码。然后,使用Traceview查看无操作onTick()调用的开销是否明显。最有可能的是,它不会。

  

但我想改变线程优先级

如果我理解正确的情况,那不是一个好主意,因为它不是你的主题。而且,我相信你将会被称为〜300次,就好像这个库被编码为每秒召唤你~30次,它可能使用Timer或其他应该相对免疫的东西线程优先级。

  

无论其他什么,我的上述代码是否正确(在同步和其他编程方面)?

就个人而言,我会使用java.util.concurrentjava.util.concurrent.atomic中的内容,而不是低级wait() / notify() / volatile。 Doug Lea比我聪明。 : - )