【发布时间】:2012-05-29 20:15:58
【问题描述】:
我知道您可以获得更多自定义,但使用并发库类是否比仅使用库存 AsyncTask 或仅创建线程并调用 run 有性能(内存/速度)优势?
【问题讨论】:
-
这个包是,afaik,如果你需要完成(或排队)繁重的线程/并行任务时使用。如果你只需要做一些简单的后台任务,你应该坚持简单的:)
标签: java android multithreading java.util.concurrent
我知道您可以获得更多自定义,但使用并发库类是否比仅使用库存 AsyncTask 或仅创建线程并调用 run 有性能(内存/速度)优势?
【问题讨论】:
标签: java android multithreading java.util.concurrent
如果您查看 AsyncTask source code,您会发现它全部基于 FutureTask 和来自 java.util.concurrent.* 的其他类。
我想使用AsyncTask 更方便,而纯粹的FutureTask 只会带来一点好处(如果有的话)。虽然您可以选择使用来自java.util.concurrent.* 的其他 API 来完成更复杂的任务。
【讨论】:
AsyncTask 带来的主要是易用性。这种工作范式,在后台运行这个方法,而在 UI 线程上的这个其他方法对可用性很有好处(尽管我通过创建 vanilla AsyncTask 的子类进行了改进,使异常处理更简单)。我认为 AsyncTask 非常适合使用请求-响应类型的调用来调用服务。但是,并非所有类型的并发都对 AsyncTask 有效。
现在,有些任务不适合 AsyncTask。例如,如果您想一次从服务器加载多个图像。 AsyncTask 可能不是最佳选择。一方面,AsyncTasks 只能运行一次并且不能重新启动。 AsyncTasks 拥有他们运行后台方法的线程,并且该线程不能被重用或共享。因此,如果您有 10 或 20 个图像,则意味着如果您使用 AsyncTasks,则需要创建和关闭 10 或 20 个线程。或者一次加载所有图像,这意味着在通过 20 次单独调用从服务器完全加载所有图像之前,您的 UI 不会更新。要么你为更好的 UI 响应支付更多的内存、资源等,要么你的 UI 为更低的开销付出了代价。两者都不是很好。
更好的选择是加载一个线程一次,发送几个轻量级作业来运行,然后将这些作业发回 UI 线程。我创建了自己的版本,例如我称之为 PipelineHandler 的 AsyncTask,它创建一个线程,并运行发布到它的作业。这些作业与 AsyncTask 非常相似,因为它们有一个在 UI 线程上调用的方法,以及另一个在 UI 线程上调用以执行更新的方法。这样做的好处是我可以利用单个线程来运行任意数量的作业。而且我可以根据需要轻松扩展为队列服务的线程,而无需更改配置选项以外的任何内容。在幕后,它使用 Java 并发类 ExecutorService,但也利用 Handler 提供在 UI 线程上运行某些东西的能力。所以它结合了 Java Concurrent lib 和 Android lib 来构建这个。
因此,为了回答您的问题,我认为 AsyncTask 非常适合服务请求-响应类型调用等单次作业,但不适用于下载图像或下载文件等批处理,尤其是在您必须同时进行多次调用的情况下。 Java 并发库可以在帮助您执行这些类型的任务方面发挥作用,但由于它们只解决了一半的问题,即在线程上运行事物,因此受到限制。 Java 并发库适合批处理作业运行,但不适合与 UI 线程交互。因此,您必须经常将它们组合在一起才能获得解决方案。
【讨论】:
AsyncTask 主要与桌面上的SwingWorker 相当,而不是并发 API。它在后台使用线程,但提供了帮助您在 UI 线程中与 UI 组件交互的方法。
【讨论】: