图的左侧是接口,图的右侧是这些接口的具体类。注意Executor是没有直接具体实现的。
Executor接口:是用来执行Runnable任务的,它只定义一个方法:
•execute(Runnable command):执行Ruannable类型的任务
ExecutorService接口:ExecutorService继承了Executor的方法,并提供了执行Callable任务和中止任务执行的服务,其定义的方法主要有:
•submit(task):可用来提交Callable或Runnable任务,并返回代表此任务的Future对象
•invokeAll(collection of tasks):批处理任务集合,并返回一个代表这些任务的Future对象集合
•shutdown():在完成已提交的任务后关闭服务,不再接受新任务
•shutdownNow():停止所有正在执行的任务并关闭服务。
•isTerminated():测试是否所有任务都执行完毕了。
•isShutdown():测试是否该ExecutorService已被关闭
ScheduledExecutorService接口在ExecutorService的基础上,ScheduledExecutorService提供了按时间安排执行任务的功能,它提供的方法主要有:
•schedule(task, initDelay): 安排所提交的Callable或Runnable任务在initDelay指定的时间后执行。
•scheduleAtFixedRate():安排所提交的Runnable任务按指定的间隔重复执行
•scheduleWithFixedDelay():安排所提交的Runnable任务在每次执行完后,等待delay所指定的时间后重复执行。
重要的Executors类
虽然以上提到的接口有其实现的具体类,但为了方便Java 5.0建议使用Executors的工具类来得到Executor接口的具体对象,需要注意的是Executors是一个类,不是Executor的复数 形式。Executors提供了以下一些static的方法:
•callable(Runnable task):将Runnable的任务转化成Callable的任务
•newSingleThreadExecutor:产生一个ExecutorService对象,这个对象只有一个线程可用来执行任务,若任务多于一个,任务将按先后顺序执行。
•newCachedThreadPool():产生一个ExecutorService对象,这个对象带有一个线程池,线程池的大小会根据需要调整,线程执行完任务后返回线程池,供执行下一次任务使用。
•newFixedThreadPool(int poolSize):产生一个ExecutorService对象,这个对象带有一个大小为poolSize的线程池,若任务数量大于poolSize,任务会被放在一个queue里顺序执行。
•newSingleThreadScheduledExecutor:产生一个ScheduledExecutorService对象,这个对象的线程池大小为1,若任务多于一个,任务将按先后顺序执行。
•newScheduledThreadPool(int poolSize):产生一个ScheduledExecutorService对象,这个对象的线程池大小为poolSize,若任务数量大于poolSize,任务会在一个queue里等待执行
举例说明:
应用Executors来建立Thread pool
有时候您需要建立一堆Thread来执行一些小任务,然而频繁的建立Thread有时会是个开销,因为Thread的建立必须与作业系统互动,如果能建立一个Thread pool来管理这些小的Thread并加以重复使用,对于系统效能会是个改善的方式。
您可以使用Executors来建立Thread pool,Executors有几个static方法,列出如下:
方法说明newCachedThreadPool建立可以快取的Thread,每个Thread预设可idle 60秒newFixedThreadPool
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)包括固定数量的ThreadnewSingleThreadExecutor
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)只有一个Thread,循序的执行指定给它的每个任务newScheduledThreadPool可排程的ThreadnewSingleThreadScheduledExecutor单一可排程的Thread
举个简单的实例,下面的程式使用newFixedThreadPool方法建立Thread pool,当中包括五个可以重复使用的Thread,您可以指定Runnable物件给它,程式中会产生十个Runnable物件,由于Thread pool中只有五个可用的Thread,所以后来建立的五个Runnable必须等待有空闲的Thread才会被执行:
•ExecutorDemo.java
代码如下:
package onlyfun.caterpillar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorDemo {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
for(int i = 0; i 10; i++) {
final int count = i;
service.submit
(new Runnable() {
public void run() {
System.out.println(count);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
service.shutdown(); // 最后记得关闭Thread pool
}
}
submit()方法也接受实作Callable介面的物件,最后传回Future物件,可以取得Callable执行过后的传回结果。如果想利用Executors进行排程,例如排定某个工作30秒后执行:
代码如下:
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( );
scheduler.schedule(new Runnable( ) {
public void run() {
// 排程工作
}
},
30, TimeUnit.SECONDS);
或排定某个工作5秒后执行,之后每30秒执行一次:
代码如下:
final ScheduledFuture future = scheduler.scheduleAtFixedRate(new Runnable( ) {
public void run() {
// 排程工作
System.out.println("t");
}
},
0, 5, TimeUnit.SECONDS);
// 排定 60 秒后取消future
scheduler.schedule(new Runnable( ) {
public void run( ) {
future.cancel(false);
}
}, 60, TimeUnit.SECONDS);
如上所示,想要取消排程任务,可以呼叫ScheduledFuture的cancel()方法。