Android线程池

来源:互联网 发布:sai在mac虚拟机没压感 编辑:程序博客网 时间:2024/06/16 10:58

推荐的文章: http://android.jobbole.com/82092/

在Android中耗时操作是需要在子线程中运行的,因为主线程执行耗时操作会出现ANR异常,因此对于一些耗时操作(比如I/O操作,网络请求,数据库操作),需要放到子线程去运行。
而如果程序中需要处理大批量的耗时操作的话,对于每一个耗时任务如果都需要开启一个新的线程的话,由于手机的CPU内核数量是有限的,也就是说同一时间CPU只能执行有限的任务(实际上对于每个单独的内核来说,执行多个任务时其实是在不同的任务间不停地切换的,只是这种切换是微秒级别的,所以给我们的感觉是CPU在并行的执行任务),也就是说如果同一时间开启过多的线程的话,手机就会显得特别卡顿。另外现成的创建和销毁线程也是比较耗费系统资源的,所以这种情况下如果使用线程池来调度任务就会比较好。

而假如这个程序有很多地方需要开启大量线程来处理任务,将导致系统的性能表现的非常糟糕,主要的影响如下:
1、线程的创建和销毁都需要时间,当有大量的线程创建和销毁时,那么这些时间的消耗则比较明显,将导致性能上的缺失

2、大量的线程创建、执行和销毁是非常耗cpu和内存的,这样将直接影响系统的吞吐量,导致性能急剧下降,如果内存资源占用的比较多,还很可能造成OOM

3、大量的线程的创建和销毁很容易导致GC频繁的执行,从而发生内存抖动现象,而发生了内存抖动,对于移动端来说,最大的影响就是造成界面卡顿

使用线程池管理线程的优点

1、线程的创建和销毁由线程池维护,一个线程在完成任务后并不会立即销毁,而是由后续的任务复用这个线程,从而减少线程的创建和销毁,节约系统的开销

2、线程池旨在线程的复用,这就可以节约我们用以往的方式创建线程和销毁所消耗的时间,减少线程频繁调度的开销,从而节约系统资源,提高系统吞吐量

3、在执行大量异步任务时提高了性能

4、Java内置的一套ExecutorService线程池相关的api,可以更方便的控制线程的最大并发数、线程的定时任务、单线程的顺序执行等

Android中的线城池是基于Java实现的,Java中Executor是一个线程池的接口,具体的实现是由ThreadPoolExecutor实现的,ThreadPoolExecutor中定义了核心线程数,最大线程数,任务队列,失效时间之类的东西,当创建好一个线程池之后,直接调用ThreadPoolExecutor对象的execute(Runnable r)方法就可以了,这里传进来一个Runnable对象,具体的执行调度线程过程由线程池完成。


Executor 简介

在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逃逸问题——如果我们在构造器中启动一个线程,因为另一个任务可能会在构造器结束之前开始执行,此时可能会访问到初始化了一半的对象用Executor在构造器中。
Executor框架包括:线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。

在java代码中 Executor是一个接口,只有一个方法。

public interface Executor {    /**     * Executes the given command at some time in the future.  The command     * may execute in a new thread, in a pooled thread, or in the calling     * thread, at the discretion of the {@code Executor} implementation.     * @param command the runnable task     * @throws RejectedExecutionException if this task cannot be     * accepted for execution     * @throws NullPointerException if command is null     */     void execute(Runnable command);    }

ExecutorService

ExecutorService 是一个接口,继承 Executor ,除了有execute( Runnable command) 方法外,还拓展其他的方法:

public interface ExecutorService extends Executor {}

void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)

<T> Future<T> submit(Callable<T> task); //提交一个任务

<T> Future<T> submit(Runnable task, T result); //提交一个任务
Future<?> submit(Runnable task); //提交一个任务

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks);

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit);

<T> T invokeAny(Collection<? extends Callable<T>> tasks);

<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit);

import java.util.concurrent.Executors;  import java.util.concurrent.LinkedBlockingQueue;  import java.util.concurrent.ThreadPoolExecutor;  import java.util.concurrent.TimeUnit;  /**  * 线程池管理 管理整个项目中所有的线程,所以不能有多个实例对象  */  public class ThreadPoolManager {  /**  * 单例设计模式(饿汉式)  *  单例首先私有化构造方法,然后饿汉式一开始就开始创建,并提供get方法  */  private static ThreadPoolManager mInstance = new ThreadPoolManager();  public static ThreadPoolManager getInstance() {      return mInstance;  }

线程池的使用

private int corePoolSize;//核心线程池的数量,同时能够执行的线程数量  private int maximumPoolSize;//最大线程池数量,表示当缓冲队列满的时候能继续容纳的等待任务的数量  private long keepAliveTime = 1;//存活时间  private TimeUnit unit = TimeUnit.HOURS;  private ThreadPoolExecutor executor;  private ThreadPoolManager() {      /**      * 给corePoolSize赋值:当前设备可用处理器核心数*2 + 1,能够让cpu的效率得到最大程度执行(有研究论证的)      */      corePoolSize = Runtime.getRuntime().availableProcessors()*2+1;      maximumPoolSize = corePoolSize; //虽然maximumPoolSize用不到,但是需要赋值,否则报错      executor = new ThreadPoolExecutor(              corePoolSize, //当某个核心任务执行完毕,会依次从缓冲队列中取出等待任务              maximumPoolSize, //5,先corePoolSize,然后new LinkedBlockingQueue<Runnable>(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的              keepAliveTime, //表示的是maximumPoolSize当中等待任务的存活时间              unit,               new LinkedBlockingQueue<Runnable>(), //缓冲队列,用于存放等待任务,Linked的先进先出              Executors.defaultThreadFactory(), //创建线程的工厂              new ThreadPoolExecutor.AbortPolicy() //用来对超出maximumPoolSize的任务的处理策略              );  }  /**  * 执行任务  */  public void execute(Runnable runnable){      if(runnable==null)return;      executor.execute(runnable);  }  /**  * 从线程池中移除任务  */  public void remove(Runnable runnable){      if(runnable==null)return;      executor.remove(runnable);  }  }
0 0