- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在尝试同时运行两个 AsyncTask。 (平台为Android 1.5,HTC Hero。)但是,只有第一个被执行。这是一个简单的 fragment 来描述我的问题:
public class AndroidJunk extends Activity {
class PrinterTask extends AsyncTask<String, Void, Void> {
protected Void doInBackground(String ... x) {
while (true) {
System.out.println(x[0]);
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new PrinterTask().execute("bar bar bar");
new PrinterTask().execute("foo foo foo");
System.out.println("onCreate() is done.");
}
}
我期望的输出是:
onCreate() is done.
bar bar bar
foo foo foo
bar bar bar
foo foo foo
等等。但是,我得到的是:
onCreate() is done.
bar bar bar
bar bar bar
bar bar bar
第二个 AsyncTask 永远不会被执行。如果我改变 execute() 语句的顺序,只有 foo 任务会产生输出。
我是否遗漏了一些明显的东西和/或做了一些愚蠢的事情?不能同时运行两个 AsyncTask 吗?
编辑:我意识到有问题的手机运行 Android 1.5,我更新了问题描述。因此。运行 Android 2.1 的 HTC Hero 没有这个问题。嗯……
最佳答案
AsyncTask 使用线程池模式来运行来自 doInBackground() 的内容。问题最初是(在早期的 Android 操作系统版本中)池大小仅为 1,这意味着一堆 AsyncTask 没有并行计算。但后来他们修复了这个问题,现在大小为 5,所以最多 5 个 AsyncTask 可以同时运行。不幸的是,我不记得他们在哪个版本中改变了这一点。
更新:
这是当前 (2012-01-27) API 对此的说明:
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. After HONEYCOMB, it is planned to change this back to a single thread to avoid common application errors caused by parallel execution. If you truly want parallel execution, you can use the executeOnExecutor(Executor, Params...) version of this method with THREAD_POOL_EXECUTOR; however, see commentary there for warnings on its use.
DONUT 是 Android 1.6,HONEYCOMB 是 Android 3.0。
更新:2
查看 kabuko
在 Mar 7 2012 1:27
发表的评论。
事实证明,对于使用“允许多个任务并行运行的线程池”的 API(从 1.6 开始,到 3.0 结束),同时运行的 AsyncTask 的数量取决于传递执行的任务数量已经,但还没有完成他们的 doInBackground()
。
这是我在 2.2 上测试/确认的。假设您有一个自定义 AsyncTask,它在 doInBackground()
中只休眠一秒钟。 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,则可以配置延迟任务队列的大小。
正如@Knossos 提到的,有一个选项可以使用支持 v.4 库中的 AsyncTaskCompat.executeParallel(task, params);
来并行运行任务,而无需担心 API 级别。此方法在 API 级别 26.0.0 中已弃用。
更新:3
这是一个简单的测试应用,用于处理任务数量、串行与并行执行:https://github.com/vitkhudenko/test_asynctask
更新:4(感谢@penkzhou 指出这一点)
从 Android 4.4 开始,AsyncTask
的行为与 UPDATE: 2 部分中描述的不同。有is a fix防止 AsyncTask
创建过多线程。
在 Android 4.4 (API 19) AsyncTask
之前有以下字段:
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
在 Android 4.4 (API 19) 中,上述字段更改为:
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
此更改将队列大小增加到 128 项,并将最大线程数减少到 CPU 内核数 * 2 + 1。应用仍然可以提交相同数量的任务。
关于android - 同时运行多个 AsyncTask —— 不可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4068984/
好的,所以我想从批处理文件运行我的整个工作环境... 我想要实现什么...... 打开新的 powershell,打开我的 API 文件夹并从该文件夹运行 VS Code 编辑器(cd c:\xy;
我正在查看 Cocoa Controls 上的示例并下载了一些演示。我遇到的问题是一些例子,比如 BCTabBarController ,不会在我的设备上构建或启动。当我打开项目时,它看起来很正常,没
我刚刚开始学习 C 语言(擅长 Java 和 Python)。 当编写 C 程序(例如 hello world)时,我在 ubuntu cmd 行上使用 gcc hello.c -o hello 编译
我在 php 脚本从 cron 开始运行到超时后注意到了这个问题,但是当它从命令行手动运行时这不是问题。 (对于 CLI,PHP 默认的 max_execution_time 是 0) 所以我尝试运行
我可以使用命令行运行测试 > ./node_modules/.bin/wdio wdio.conf.js 但是如果我尝试从 IntelliJ 的运行/调试配置运行它,我会遇到各种不同的错误。 Fea
Error occurred during initialization of VM. Could not reserve enough space for object heap. Error: C
将 Anaconda 安装到 C:\ 后,我无法打开 jupyter 笔记本。无论是在带有 jupyter notebook 的 Anaconda Prompt 中还是在导航器中。我就是无法让它工作。
我遇到一个问题,如果我双击我的脚本 (.py),或者使用 IDLE 打开它,它将正确编译并运行。但是,如果我尝试在 Windows 命令行中运行脚本,请使用 C:\> "C:\Software_Dev
情况 我正在使用 mysql 数据库。查询从 phpmyadmin 和 postman 运行 但是当我从 android 发送请求时(它返回零行) 我已经记录了从 android 发送的电子邮件是正确
所以这个有点奇怪 - 为什么从 Java 运行 .exe 文件会给出不同的输出而不是直接运行 .exe。 当 java 在下面的行执行时,它会调用我构建的可与 3CX 电话系统配合使用的 .exe 文
这行代码 Environment.Is64BitProcess 当我的应用单独运行时评估为真。 但是当它在我的 Visual Studio 单元测试中运行时,相同的表达式的计算结果为 false。 我
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我写了一个使用 libpq 连接到 PostgreSQL 数据库的演示。 我尝试通过包含将 C 文件连接到 PostgreSQL #include 在我将路径添加到系统变量 I:\Program F
如何从 Jenkins 运行 Android 模拟器来运行我的测试?当我在 Execiute Windows bath 命令中写入时,运行模拟器的命令: emulator -avd Tester 然后
我已经配置好东西,这样我就可以使用 ssl 登录和访问在 nginx 上运行的 errbit 我的问题是我不知道如何设置我的 Rails 应用程序的 errbit.rb 以便我可以运行测试 nginx
我编写了 flutter 应用程序,我通过 xcode 打开了 ios 部分并且应用程序正在运行,但是当我通过 flutter build ios 通过 vscode 运行应用程序时,我得到了这个错误
我有一个简短的 python 脚本,它使用日志记录模块和 configparser 模块。我在Win7下使用PyCharm 2.7.1和Python 3.3。 当我使用 PyCharm 运行我的脚本时
我在这里遇到了一些难题。 我的开发箱是 64 位的,windows 7。我所有的项目都编译为“任何 CPU”。该项目引用了 64 位版本的第 3 方软件 当我运行不使用任何 Web 引用的单元测试时,
当我注意到以下问题时,我正在做一些 C++ 练习。给定的代码将不会在 Visual Studio 2013 或 Qt Creator 5.4.1 中运行/编译 报错: invalid types 'd
假设我有一个 easteregg.py 文件: from airflow import DAG from dateutil import parser from datetime import tim
我是一名优秀的程序员,十分优秀!