这便是执行器接口,顾名思义,它接受一个 Runnable 对象,并可以大概执行它。至于如何执行,交由具体的实现类负责,目前至少有以下四种执行方式 ③
在当前线程中同步执行
总是新开线程来异步执行
只利用一个线程来异步串行执行
利用多个线程来并发执行
本小节将以一个浅易的线程池方式来实现 Executor。
编写只有一个线程的线程池
这是线程池的最简形式,实当代码也非常简单,如下所示
public class SingleThreadPoolExecutor implements Executor {
// 任务队列
private final Queue<Runnable> tasks = new LinkedBlockingDeque<>();
// 直接将任务添加到队列中
@Override
public void execute(Runnable task) {
tasks.offer(task);
}
public SingleThreadPoolExecutor() {
// 在构造函数中,直接创建一个线程,作为为线程池的唯一任务执行线程
// 它将在被创建后立即执行,执行逻辑为:
// 1. 从队列中获取任务
// 2. 如果获取到任务,则执行它,执行完后,返回第1步
// 3. 如果未获取到任务,则简短休息,继续第1步
Thread taskRunner = new Thread(() -> {
Runnable task;
while (true) {
task = tasks.poll();
if (task != null) {
task.run();
continue;
}
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
});
taskRunner.start();
}
}
复制代码
上述的单线程执行器实现中,执行使命的线程是永久不会停止的,获取到使命时,就执行它,没有获取到,就不停不停的获取。下面是这个执行器的测试代码:
[code]public class SingleThreadPoolTest { public static void main(String[] args) throws InterruptedException { SingleThreadPoolExecutorstp stp= new SingleThreadPoolExecutor(); // 连续添加 5 个使命 for (int i = 1; i submit(Runnable task);