Android线程池(一)

本篇文章主要介绍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 }

结果依次输出,相当于顺序执行各个任务。

原文地址:https://www.cnblogs.com/all88/p/5195443.html