0

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

@Override
public void onTick() {

    // do many useful operations

}

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

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

在这种情况下有什么解决方案可以节省 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. 有点离题,但我认为它不值得一个专门的问题:更改线程的优先级是否有任何重大开销?有没有什么通用的指导方针可以做这样的事情?(例如多久可以完成一次等)
4

1 回答 1

2

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

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

但我也想更改线程优先级

这不是一个好主意,因为它不是你的线程,如果我正确理解场景的话。此外,我相信无论如何你都会被调用约 300 次,就好像库被编码为每秒调用约 30 次一样,它很可能使用 aTimer或其他应该相对不受线程优先级影响的东西。

不管其他一切,我上面的代码是否正确(在同步和其他编程方面)?

就个人而言,我会使用 and 的东西java.util.concurrentjava.util.concurrent.atomic而不是低级的wait()// notify()volatileDoug Lea 比我聪明。:-)

于 2012-12-09T17:25:10.117 回答