java - Android Thread、Handler 和 HandlerThreads 的并发性
问题描述
好的。所以我正在使用 Camera2 API 并尝试在后台处理所有工作,以便 UI 响应。我已经实现了一个 HandlerThread 和一个 Handler 来将任务放入其中,如下所示:
private void startBackgroundThread(){
backgroundHandlerThread = new HandlerThread("BackgroundThread");
backgroundHandlerThread.start();
backgroundHandler = new Handler(backgroundHandlerThread.getLooper());
}
然后我像这样发布可运行文件:
backgroundHandler.post(new ImageSaver(reader.acquireLatestImage()));
问题是我对发布的每个可运行文件都使用相同的处理程序(backgroundHander),并且遇到了一些严重的性能问题。这告诉我,我没有正确地进行并发,但是在查看了几个小时的文档后,我无法找到这些类的正确用法。什么是正确的方法?
- 为我在 HandlerThread 中发布的每个可运行文件创建多个处理程序?
- 为每种类型的可运行对象创建多个 HandlerThread?
在此先感谢并尽量不要对我苛刻,因为我对此很陌生。
解决方案
每个HandlerThread都有一个Looper,它为线程运行一个消息循环。每个 Looper 都有一个MessageQueue,它保存着发送到 Looper 的消息列表。消息和 Runnable 由Handler发送到 MessageQueue 。每一个都在它们从消息队列中出来时被执行。这个过程是阻止您“真正”并发的原因。
ExecutorService可以在这里工作。ExecutorService 允许提交和执行多个 Runnable。从上面的代码片段来看,好像您正在使用 HandlerThread 将工作置于主线程或 UI 线程的后台。如果您不尝试将工作或其结果传递回主线程,则常规线程和 ExecutorService 也可以正常工作。
举个例子
...
Executor executor = Executors.newFixedThreadPool(numThreads);
executor.submit(new ImageSaver(reader.acquireLatestImage()));
// submit Runnables as needed
executor.shutdownNow(); // VERY IMPORTANT OR YOU WILL CREATE A MEMORY LEAK!
...
如果您需要与 UI 线程进行通信,则需要提供 ExecutorService 接口的实现,如其文档的ExecutorService使用示例部分中的示例。
推荐阅读
- python - Python Problem: applied problem for building function for retrieving the elements from the list
- javascript - 编辑高阶和低阶组件之间的状态
- python - 如何从 Pytorch 中的二维张量列表中获取列
- php - Laravel 插入的数据未保存到数据库中
- shell - 如果超过 15 天,如何编写 shell 脚本来删除包含 PII 数据的日志
- html - 我可以使用 CSS 转换来使我的整个页面容器响应吗?
- r - 使用循环或 IF 函数根据条件在数据框中添加值 - 在 R 代码中
- reactjs - 如何使用 React 在类组件中编写此代码
- go - go 中如何隐式转换类型别名?
- javascript - 在 React 中延迟 Auth0 重定向,直到收到用户凭据