Android线程池

tech2023-12-03  37

一:使用线程池的原因

在android开发中经常会使用多线程来处理相关任务,如果我们老是使用新建Thread方法来处理相关事务,会存在一些问题:

在任务众多的情况下,系统要为每一个任务创建一个线程,而任务执行完毕后会销毁每一个线程,所以会造成线程频繁地创建与销毁。从而会占用大量资源,多个线程在抢夺资源中会造成UI线程的卡顿,同时多个线程频繁地销毁,会频繁地调用GC机制,这会使性能降低,又非常耗时。这个时候我们就需要统一管理这些线程!

因此我们就需要用到线程池 线程池使用的好处: 1 使用起来很方便,对多个线程进行统一地管理,避免资源竞争中出现的问题。

2 对线程进行复用,线程在执行完任务后不会立刻销毁,而会等待另外的任务,这样就不会频繁地创建、销毁线程和调用GC。

二:几种常见的线程池 1:ThreadPoolExecutor 基本线程池 2:FixedThreadPool (执行长期的任务,性能好很多) 3:CachedThreadPool (适用于有大量需要立即执行的耗时少的任务的情况) 4:SingleThreadPool(一个任务一个任务执行的场景是的单个的FixedThreadPool ) 5:ScheduledThreadPool(周期性执行任务的场景)

三:线程池用法 创建线程池,主要是利用ThreadPoolExecutor这个类,而这个类有几种构造方法,其中参数最多的一种构造方法如下:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { ... }

corePoolSize: 该线程池中核心线程的数量 maximumPoolSize:该线程池中最大线程数量。(区别于corePoolSize) keepAliveTime:从字面上就可以理解,是非核心线程空闲时要等待下一个任务到来的时间,当任务很多,每个任务执行时间很短的情况下调大该值有助于提高线程利用率。注意:当allowCoreThreadTimeOut属性设为true时,该属性也可用于核心线程。 unit:上面时间属性的单位 workQueue:任务队列

ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。 LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。 PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。 DelayQueue:一个使用优先级队列实现的无界阻塞队列。 SynchronousQueue:一个不存储元素的阻塞队列。 LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。 LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

adFactory:线程工厂,可用于设置线程名字等等,一般无须设置该参数。

1,新建线程池

//创建基本线程池 final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,5,1,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(100)); //创建fixed线程池,参数为核心线程数,只有核心线程,无非核心线程,并且阻塞队列无界。采用LinkedBlockingQueue final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5); //创建Cached线程池,没有核心线程,只有非核心线程,并且每个非核心线程空闲等待的时间为60s,采用SynchronousQueue队列。 final ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); //创建Single线程池,只有一个核心线程,当被占用时,其他的任务需要进入队列等待,采用LinkedBlockingQueue final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); //创建Scheduled线程池,延迟启动任务,使用方法scheduledThreadPool.(runnable,10,TimeUnit.SECONDS); final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);

2 加入线程,几种线程池的使用方法都一样,除了ScheduledExecutorService ;

threadPoolExecutor.execute(new Runnable() { @Override public void run() { try { //处理相应事务 } catch (InterruptedException e) { e.printStackTrace(); } } });

ScheduledExecutorService 使用方法

//10是指延时10s启动 scheduledThreadPool.(runnable,10,TimeUnit.SECONDS);

3 其他方法

1.shutDown() 关闭线程池,不影响已经提交的任务

2.shutDownNow() 关闭线程池,并尝试去终止正在执行的线程

3.allowCoreThreadTimeOut(boolean value) 允许核心线程闲置超时时被回收

4.submit 一般情况下我们使用execute来提交任务,但是有时候可能也会用到submit,使用submit的好处是submit有返回值。

5.beforeExecute() - 任务执行前执行的方法

6.afterExecute() -任务执行结束后执行的方法

7.terminated() -线程池关闭后执行的方法

最新回复(0)