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); } }
- Java(线程)Android线程池
- Android线程,线程池相关
- Android 线程和线程池
- Android线程与线程池
- Android线程和线程池
- Android 线程和线程池
- Android线程和线程池
- Android线程与线程池
- Android线程和线程池
- Android线程与线程池
- Android 线程和线程池
- Android线程和线程池
- Android线程和线程池(四)--Android线程池
- Android ExecutorService线程池
- Android 线程池管理 .
- Android 线程池管理
- Android ExecutorService线程池
- Android 线程池管理
- javascript-clipboard.js教程
- Highcharts应用--动态玫瑰图
- 为什么我们喜欢用 async function
- Android ListView工作原理完全解析,带你从源码的角度彻底理解
- 【opencv】python3 将图片生成视频文件
- Android线程池
- hdu 6031 Innumerable Ancestors
- Android数据库
- 对ASP.NET网站高性能和多并发的设计的讨论
- gradle使用遇到的问题,及tinker初用
- 文件指针与文件位置指针,文件位置指针相关的库函数
- MediaCodec_loop 崩溃
- NSSearchPathForDirectoriesInDomains详细用法
- [MethodImpl(MethodImplOptions.InternalCall), WrapperlessIcall]