android AsyncTask 只能在线程池里单个运行的问题

android 的AysncTask直接调用Execute会在在一个线程池里按调用的先后顺序依次执行。

如果应用的所有网络获取都依赖这个来做,当有一个网络请求柱塞,就导致其它请求也柱塞了。

在3.0 以后引入了新的方法。可以不在一个线程池里运行。

class TaskHelper {

    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task) {
        execute(task, (P[]) null);
    }

    @SuppressLint("NewApi")
    public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task, P... params) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
        } else {
            task.execute(params);
        }
    }
}

asyncTask.execute

Note: this function schedules the task on a queue for a single background thread or pool of threads depending on the platform version. When first introduced, AsyncTasks were executed serially on a single background thread. Starting with android.os.Build.VERSION_CODES.DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. After android.os.Build.VERSION_CODES.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 version of this method with THREAD_POOL_EXECUTOR; however, see commentary there for warnings on its use.

This method must be invoked on the UI thread.必须UI线程中调用

注意:这个函数让任务是以单线程队列方式或线程池队列方式运行,依赖于平台版本而有所不同。asyncTask首次引入时,这个函数会让任务以后台单线程串行方式执行。从android.os.Build.VERSION_CODES.DONUT(android 1.6)开始,它让允许任务在线程池中多任务并行执行。但在 android.os.Build.VERSION_CODES.HONEYCOMB(android 3.0)之后,它又该回去了,变成了单线程执行的模式,原因是多线程并行执行容易引发问题。如果你真想并行执行任务,你可以使用另外一个版本:使用THREAD_POOL_EXECUTOR参数的executeOnExecutor方法,但要注意使用警告提示

anyncTask.executeOnExecutor

This method is typically used with THREAD_POOL_EXECUTOR to allow multiple tasks to run in parallel on a pool of threads managed by AsyncTask, however you can also use your own Executor for custom behavior.

Warning: Allowing multiple tasks to run in parallel from a thread pool is generally not what one wants, because the order of their operation is not defined. For example, if these tasks are used to modify any state in common (such as writing a file due to a button click), there are no guarantees on the order of the modifications. Without careful work it is possible in rare cases for the newer version of the data to be over-written by an older one, leading to obscure data loss and stability issues. Such changes are best executed in serial; to guarantee such work is serialized regardless of platform version you can use this function with SERIAL_EXECUTOR. 
This method must be invoked on the UI thread.
Parameters:
exec The executor to use. THREAD_POOL_EXECUTOR is available as a convenient process-wide thread pool for tasks that are loosely coupled.

这个方法通常和THREAD_POOL_EXECUTOR一起使用,允许多个任务在由AsyncTask管理的线程池中并行执行,但是您你也可以使用自定义行为的Executor。

警告:因为执行操作顺序并未定义,通常情况下,允许多个任务在线程池中并行执行,其结果并非是你想要的。例如:这些任务都要去修改某个状态值(诸如点击按钮写文件),因为没有确定的修改顺序,旧的修改可能会覆盖新修改的版本内容,导致不稳定数据丢失而变成一个稳定的问题。因此这种任务最好是串行执行;确保这些任务串行执行而不依赖于平台版本的方法是,使用SERIAL_EXECUTOR

时间: 2024-10-17 09:52:29

android AsyncTask 只能在线程池里单个运行的问题的相关文章

Android多线程编程之线程池学习篇(一)

Android多线程编程之线程池学习篇(一) 一.前言 Android应用开发中多线程编程应用比较广泛,而应用比较多的是ThreadPoolExecutor,AsyncTask,IntentService,HandlerThread,AsyncTaskLoader等,为了更详细的分析每一种实现方式,将单独成篇分析.后续篇章中可能涉及到线程池的知识,特此本篇分析为何使用线程池,如何使用线程池以及线程池的使用原理. 二.Thread Pool基础 进程代表一个运行中的程序,一个运行中的Android

分析AsyncTask中的线程池

问题由来: 之前看到一篇博文,说AsyncTask不适合运行多任务, 多个任务不会异步执行, 当时只是印象里记住了一下也不确定, 今天把代码看了看, 把原因写出来. 问题的代码演示: 1 public class AsyncTaskDemo extends AsyncTask<String, Integer, String>{ 2 private final static String TAG = "AsyncTaskTest"; 3 4 @Override 5 prote

Android性能优化之线程池策略和对线程池的了解

线程的运行机制 1. 开启线程过多,会消耗cpu 2. 单核cpu,同一时刻只能处理一个线程,多核cpu同一时刻可以处理多个线程 3. 操作系统为每个运行线程安排一定的CPU时间----`时间片`,系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因为时间相当短,多个线程频繁地发生切换,因此给用户的感觉就是好像多个线程同时运行一样,但是如果计算机有多个CPU,线程就能真正意义上的同时运行了. 线程池的作用 1. 线程池是预先创建线程的一种技术.线程池在还没有任务到来之前,创建一定数

如何获取线程池ThreadPoolExecutor正在运行的线程

如何获取线程池ThreadPoolExecutor正在运行的线程?这里有两种方法,如下代码: package com.itbac.thread; import java.util.HashSet; import java.util.Set; import java.util.concurrent.*; import java.util.stream.Stream; /** * ThreadPoolExecutor 的 beforeExecute() 和 afterExecute()方法, * 不

Android(Java)线程池:ExecutorService和Executors使用(一)

ExecutorService是线程池的一个服务,可以随时关闭线程池,是继承Executor的.Executors是个工厂类,专门创建各种线程池. public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long

多线程篇七:通过Callable和Future获取线程池中单个务完成后的结果

使用场景:如果需要拿到线程的结果,或者在线程完成后做其他操作,可以使用Callable 和 Futrue 1.定义一个线程池,向线程池中提交单个callable任务 ExecutorService threadPools=Executors.newSingleThreadExecutor(); Future<String> future=threadPools.submit(new Callable<String>() { @Override public String call(

Android(Java)线程池:ExecutorService和Executors使用(二)

一.固定大小的线程池,newFixedThreadPool: package Executor.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExecutorTest { public static void main(String[] args) { // TODO Auto-generated method stub doExecut

Android线程与线程池

一.特殊的线程 1.AsynTask 底层用到了线程池,封装了线程池和Handler,主要是为了方便开发者在子线程中更新UI 2.IntentService(不完整???) 内部采用HandlerThread来执行任务,当任务执行完毕后IntentService会自动退出,底层直接使用了线程(从任务执行的角度来看,IntentService的作用很像一个后台线程,但是IntentService是一种服务,他不容易被系统杀死从而可以尽量保证任务的执行) 3.HandlerThread 是一种具有消

线程池的理解与简单实现

池 由于服务器的硬件资源"充裕",那么提高服务器性能的一个很直接的方法就是以空间换时间,即"浪费"服务器的硬件资源,以换取其运行效率.这就是池的概念. 池是一组资源的集合,这组资源在服务器启动之初就被创建并初始化,这称为静态资源分配. 当服务器进入正式运行阶段,即开始处理客户请求的时候,如果它需要相关的资源,就可以直接从池中获取,无需动态分配.很显然,直接从池中取得所需资源比动态分配资源的速度要快得多,因为分配系统资源的系统调用都是很耗时的. 当服务器处理完一个客户