java - 当 wait() 不可用时节省 CPU

标签 java android multithreading wait

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

@Override
public void onTick() {

    // do many useful operations

}

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

最直接的解决方案是向 onTick() 发送信号,并通过 Object.wait() 以适当的同步方式使其线程 hibernate block 。然而,第三方组件的文档指出,其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. 有点偏离主题,但我认为不值得专门讨论这个问题:更改线程的优先级是否会产生重大开销?进行此类行为时是否有任何一般准则? (例如多久可以做一次等)

最佳答案

Is there a better way to save some CPU time?

我什至不会去理会那里的东西。我同意 Chris Stratton 的观点:避免做实际的工作,并删除上面显示的其余其他代码。然后,使用Traceview看看你的无所事事的开销是否onTick()调用是显而易见的。最有可能的是,它不会。

But I want to change the thread priority as well

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

Regardless of everything else, is my above code correct (in terms of synchronization and other programming aspects)?

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

关于java - 当 wait() 不可用时节省 CPU,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13789307/

相关文章:

c - 如何通过引用 pthread 启动例程来传递顺序计数器?

java - Spring 4.2.5.release 中 AbstractDependencyInjectionSpringContextTests 的等效类是什么

java - 在 Eclipse 中的单独 JVM 中运行每个 JUnit 测试?

android - 预期为 JsonObject 但为 JsonPrimitive

Android手机号码验证流程

multithreading - Ada83或Ada95是否定义了一种内存模型来支持多任务处理?

java - 尝试在服务器上的 WildFly 上访问 websocket URL 时出现 404 错误,在本地主机上完美运行

java - 使用 Netbeans 中的 JDBC 资源和 servlet

android - 是否可以通过在 "app_remove"事件上使用 Google Analytics for Firebase 触发器自动向 Android 应用程序发送推送通知

java - 可观察超时