gpt4 book ai didi

java - 使用并行线程进行不同的网络操作

转载 作者:行者123 更新时间:2023-12-02 05:35:59 25 4
gpt4 key购买 nike

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。




Improve this question




我正在编写一个应用程序,它应该首先一个接一个地运行 2 个方法,每个方法需要 2 秒来获取第一个 tokenId,然后运行 ​​3-5 次调用不同的 Web 服务来获取数据。每次调用web service需要 5 秒,所以我不想在一个一个运行它们时等待 20 秒。

获取连接然后获取 token :
connect()得到结果后,运行 getToken () .

之后,我需要显示从 3-5 web services 获得的数据,所以我想并行执行以节省一些时间。我不想等待每个完成然后运行下一个,所以我可能需要使用 3-5 个并行 Threads然后每个 Thread将数据保存到可共享的地方,毕竟在 UI 上显示数据。

一些问题:

1- 实现 connect()之后getToken()我应该运行 AsyncTask对于 connect()然后在 onPostExecute()开始一个新的AsyncTask对于 getToken()结果来自 connect() ?

2- 因为我在每个 Web 服务中的所有工作都是发送数据并等待它的到来 - 创建 3-4 Theards 是否正确?当每个人都无法调用不同的web service并得到结果 - 之后将其保存到全局位置,然后才显示它?如何实现这样的事情?

最佳答案

是的,您可以运行多达 128 个异步任务,这是在 android 中同时运行异步任务的线程池容量。阅读下面的描述或从 github 下载示例。

AsyncTask 使用线程池模式来运行来自 doInBackground() 的内容。问题最初是(在早期的 Android 操作系统版本中)池大小仅为 1,这意味着一堆 AsyncTask 没有并行计算。但后来他们修复了这个问题,现在大小为 5,所以最多 5 个 AsyncTask 可以同时运行。不幸的是,我不记得他们到底在哪个版本中改变了这一点。

以下是当前 (2012-01-27) API 对此的说明:

首次引入时,AsyncTask 在单个后台线程上串行执行。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。在 HONEYCOMB 之后,计划将其改回单线程,以避免并行执行导致的常见应用程序错误。如果你真的想要并行执行,你可以使用这个方法的 executeOnExecutor(Executor, Params...) 版本和 THREAD_POOL_EXECUTOR;但是,请参阅那里的评论以获取有关其使用的警告。

DONUT 是 Android 1.6,HONEYCOMB 是 Android 3.0。

事实证明,对于使用“允许多个任务并行运行的线程池”的 API(从 1.6 开始到 3.0 结束),同时运行的 AsyncTask 的数量取决于已经传递了多少任务执行,但是还没有完成他们的 doInBackground() 。

这是我在 2.2 上测试/确认的。假设您有一个自定义 AsyncTask,它只在 doInBackground() 中 hibernate 一秒钟。 AsyncTask 在内部使用固定大小的队列来存储延迟任务。队列大小默认为 10。如果您连续启动 15 个自定义任务,那么前 5 个将进入它们的 doInBackground(),但其余的将在队列中等待空闲的工作线程。只要前 5 个任务中的任何一个完成,从而释放一个工作线程,队列中的一个任务就会开始执行。所以在这种情况下,最多 5 个任务将同时运行。但是,如果您连续启动 16 个自定义任务,那么前 5 个将进入它们的 doInBackground(),其余 10 个将进入队列,但是对于第 16 个,将创建一个新的工作线程,因此它将立即开始执行。所以在这种情况下,最多 6 个任务将同时运行。

可以同时运行多少个任务是有限制的。由于 AsyncTask 使用的线程池执行器具有有限的最大工作线程数 (128),并且延迟任务队列的大小固定为 10,因此如果您尝试执行超过 138 个自定义任务,则应用程序将因 java.util.concurrent.RejectedExecutionException 而崩溃.

从 3.0 开始,API 允许通过 AsyncTask.executeOnExecutor(Executor exec, Params... params) 方法使用您的自定义线程池执行器。例如,如果默认 10 不是您需要的,这允许配置延迟任务队列的大小。

这是一个简单的测试应用程序,用于处理任务数量、串行与并行执行:https://github.com/vitkhudenko/test_asynctas

关于java - 使用并行线程进行不同的网络操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24967695/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com