在执行一系列带有IO操作(例如下载文件),且互不相关的异步任务时,采用多线程可以很极大的提高运行效率。线程池包含了一系列的线程,并且可以管理这些线程。例如:创建线程,销毁线程等。本文将介绍如何使用Java中的线程池执行任务。
1 任务类型
在使用线程池执行任务之前,我们弄清楚什么任务可以被线程池调用。按照任务是否有返回值可以将任务分为两种,分别是实现Runnable的任务类(无参数无返回值)和实现Callable接口的任务类(无参数有返回值)。在打代码时根据需求选择对应的任务类型。
1.1 实现Runnable接口的类
多线程任务类型,首先自然想到的就是实现 Runnable 接口的类,Runnable接口提供了一个抽象方法run,这个方法无参数,无返回值。例如:
Runnable task = newRunnable() {
@Overridepublic voidrun() {
System.out.println("Execute task.");
}
};
或者Java 8 及以上版本更简单的写法:
Runnable task = ()->{
System.out.println("Execute task.");
};
1.2 实现Callable接口的类
于Runnable一样Callable也只有一个抽象方法,不过该抽象方法有返回值。在实现该接口的时候需要制定返回值的类型。例如:
Callable callableTask = ()-> "finished";
2 线程池类型
java.util.concurrent.Executors 提供了一系列静态方法来创建各种线程池。下面例举出了主要的一些线程池及特性,其它未例举线程池的特性可由下面这些推导出来。
2.1 线程数固定的线程池 Fixed Thread Pool
顾名思义,这种类型线程池线程数量是固定的。如果线程数量设置为n,则任何时刻该线程池最多只有n个线程处于运行状态。当线程池中处于饱和运行状态时,再往线程池中提交的任务会被放到执行队列中。如果线程池处于不饱和状态,线程池也会一直存在,直到ExecuteService 的shutdown方法被调用,线程池才会被清除。
//创建线程数量为5的线程池。
ExecutorService executorService = Executors.newFixedThreadPool(5);
2.2