本篇文章主要介绍Android自带的线程池的使用。
首先要引入线程池的概念
线程池:是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。
为什么要使用线程池?
通常我们在执行多任务的时候会开启多个线程去执行不同的任务
假设在一台服务器完成一项任务的时间为T
T1 创建线程的时间
T2 在线程中执行任务的时间,包括线程间同步所需时间
T3 线程销毁的时间
显然T = T1+T2+T3。注意这是一个极度简化的假设。
可以看出T1,T3是多线程本身的带来的开销,我们渴望减少T1,T3所用的时间,从而减少T的时间。但一些线程的使用者并没有注意到这一点,
所以在程序中频繁的创建或销毁线程,这导致T1和T3在T中占有相当比例。显然这是突出了线程的弱点(T1,T3),而不是优点(并发性)。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段
或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目。
在Android中当同时并发多个网络线程时,引入线程池技术会极大地提高APP的性能。
Android自带的线程池介绍
Android本身延续了Java本身自己的线程池技术即使用:ExecutorService类
提供四种线程池分别是:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(1). newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:
1 ExecutorService cachedThreadPool =Executors.newCachedThreadPool(); 2 for (int i = 0; i < 10; i++) { 3 final int index = i; 4 try { 5 Thread.sleep(index * 1000); 6 } catch (InterruptedException e) { 7 e.printStackTrace(); 8 } 9 10 cachedThreadPool.execute(new Runnable() { 11 12 @Override 13 public void run() { 14 System.out.println(index); 15 } 16 }); 17 }
线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
(2). newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:
1 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); 2 for (int i = 0; i < 10; i++) { 3 final int index = i; 4 fixedThreadPool.execute(new Runnable() { 5 6 @Override 7 public void run() { 8 try { 9 System.out.println(index); 10 Thread.sleep(2000); 11 } catch (InterruptedException e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } 15 } 16 }); 17 }
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。
(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:
1 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); 2 scheduledThreadPool.schedule(new Runnable() { 3 4 @Override 5 public void run() { 6 System.out.println("delay 3 seconds"); 7 } 8 }, 3, TimeUnit.SECONDS);
表示延迟3秒执行。
定期执行示例代码如下:
1 scheduledThreadPool.scheduleAtFixedRate(new Runnable() { 2 3 @Override 4 public void run() { 5 System.out.println("delay 1 seconds, and excute every 3 seconds"); 6 } 7 }, 1, 3, TimeUnit.SECONDS);
表示延迟1秒后每3秒执行一次。
ScheduledExecutorService比Timer更安全,功能更强大。
(4)、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:
1 ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); 2 for (int i = 0; i < 10; i++) { 3 final int index = i; 4 singleThreadExecutor.execute(new Runnable() { 5 6 @Override 7 public void run() { 8 try { 9 System.out.println(index); 10 Thread.sleep(2000); 11 } catch (InterruptedException e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } 15 } 16 }); 17 }
结果依次输出,相当于顺序执行各个任务。