为什么需要线程池

我们在在使用线程时可以简单的 new Thread()来创建线程进行并发异步操作,但是如果逻辑比较复杂,或者频繁使用线程就会带来管理和性能的问题,线程池的出现就是为了解决这个问题。
线程池有一下几个优点:

  1. 线程重用,减少对象的创建,销毁开销,提升性能
  2. 控制线程的并发数,提高系统资源的利用率
  3. 更灵活的控制方式,如定时执行,定期执行,单线程控制等功能

线程池 ThreadPoolExecutor

Android 线程池通过 SDK 中的 ThreadPoolExecutor 类来提供线程池的功能。它的构造函数如下:

1
2
3
4
5
6
7
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

corePoolSize: 核心线程数,永久存活的线程数;
maximumPoolSize: 最大线程数,可执行,存活的最大线程数。大于等于corePoolSize;
keepAliveTime: 超过corePoolSize的线程在执行结束后的存活时间;
unit: 时间单位;
workQueue: 当向线程池提交的线程数大于maximumPoolSize后,后续的线程会交由此队列处理;
threadFactory: 线程工厂类,用来提供线程的创建;
handler: 线程池不能接受新的任务提交时调用。比如线程池关闭(executorService.shutdown())或者已提交的任务已达到maximumPoolSize和workQueue的上限。

Executors

Executors 类提供了许多常用类型的线程池构建的静态方法,我就常用的几种做个简单说明,其它可到官方文档查阅。

固定线程数的线程池 FixedThreadPool

1
2
3
4
5
6
7
8
9
10
11
12
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}

特点:最大运行线程数固定,超出指定线程数的的线程进入队列。线程会一直存活

单线程的线程(池) SingleThreadExecutor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}

特点:最大运行线程数为1,每次只运行1个线程,超出指定线程数的的线程进入队列。保证任务顺序。

无上限的线程池 CachedThreadPool

1
2
3
4
5
6
7
8
9
10
11
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}

特点:无核心线程,提交多少,执行多少。线程执行完后无新任务存活60s后销毁,有新任务重用。

带延迟功能的线程池 ScheduledThreadPool

1
2
3
4
5
6
7
8
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}

public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}

特点:指定核心线程数,无最大限制,可并发执行多个任务(任务周期可能重合,导致并发产生)。线程执行完后无新任务存活10ms后销毁,有新任务重用。可控制各个任务的周期(控制方法)。

带延迟功能的单线程(池) SingleThreadScheduledExecutor

1
2
3
4
5
6
7
8
9
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}

public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}

特点:核心线程数为1,不会并发执行,可控制周期。


不知道为啥 最后一个代码块添加高亮会截断文章。。。 先把高亮撤了。。。。