我的组件集成到第三方组件。我必须覆盖由第三方组件的高优先级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");
}
}
}
三个问题:
答案 0 :(得分:2)
有没有更好的方法来节省一些CPU时间?
我甚至不打扰那里的东西。我同意Chris Stratton:只是避免做实际工作,并删除上面显示的其他代码。然后,使用Traceview查看无操作onTick()
调用的开销是否明显。最有可能的是,它不会。
但我想改变线程优先级
如果我理解正确的情况,那不是一个好主意,因为它不是你的主题。而且,我相信你将会被称为〜300次,就好像这个库被编码为每秒召唤你~30次,它可能使用Timer
或其他应该相对免疫的东西线程优先级。
无论其他什么,我的上述代码是否正确(在同步和其他编程方面)?
就个人而言,我会使用java.util.concurrent
和java.util.concurrent.atomic
中的内容,而不是低级wait()
/ notify()
/ volatile
。 Doug Lea比我聪明。 : - )