若是查看jdk文档,会发现java线程池都源自于这个超级接口Executor,可是这个接口自己比较简单:java
public interface Executor { /** 在将来某个时间执行给定的命令。该命令可能在新的线程、已入池的线程或者正调用的线程中执行, 这由 Executor 实现决定。 * * @param command the runnable task * @throws RejectedExecutionException if this task cannot be * accepted for execution. * @throws NullPointerException if command is null */ void execute(Runnable command); }
能够看到Executor
中只有一个execute
方法。此接口提供一种将任务提交与每一个任务将如何运行的机制分离开来的方法,相比较为每一个人物调用new Thread(Runnable r).start()
,咱们更偏向于使用Executor
(执行器)来运行任务:segmentfault
Executor executor = anExecutor; executor.execute(new RunnableTask1()); executor.execute(new RunnableTask2()); ...
实现一个执行器也很简单:学习
class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { new Thread(r).start(); } }
Executor
提供的方法太少了!根本不能知足平常所需,而从它派生下来的接口ExecutorService
则显得更通用,毕竟它也是个Service。this
public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; ... }
能够看到,ExecutorService
接口中包含了咱们日常使用的线程池的绝大多数方法,其中的一些方法在上文已经介绍过了。线程
AbstractExecutorService是一个抽象类,而且实现了ExecutorService接口。code
public abstract class AbstractExecutorService implements ExecutorService
在这个类中,提供了ExecutorService
一些方法的默认实现,好比submit
,invokeAll
,首先看submit
的实现:接口
public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
其中使用了newTaskFor
方法:文档
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); }
newTaskFor
方法只是简单的将给定可调用任务包装成一个RunnableFuture
,使其具备取消运行的特性。而submit
中直接将任务交给execute()
运行.
再来看invokeAll()
:get
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { if (tasks == null) throw new NullPointerException(); //建立一个list保存全部的结果 List<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); boolean done = false; try { for (Callable<T> t : tasks) { RunnableFuture<T> f = newTaskFor(t); futures.add(f); execute(f); //运行任务 } for (Future<T> f : futures) { if (!f.isDone()) { //依次取结果 try { f.get(); //这里使用get是为了等待运行完成,若是没完成就会阻塞 } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } } done = true; return futures; } finally { if (!done) //若是发生异常,则取消全部任务 for (Future<T> f : futures) f.cancel(true); } }
续:java线程池的原理学习(二)it