这里分析一下concurrent包下的部分类!!!
1.Executor/ExecutorService
线程资源比较重要,为了复用已经创建的线程,减少在创建和销毁线程时产生的性能开销。因为创建和管理线程非常心累,并且操作系统通常对线程数有限制,所以建议使用线程池来并发执行任务,而不是每次请求进来时创建一个线程。
Executor:将任务本身和任务的执行分离(Thread而是将全部柔和到一起很不方面管理)。用于调度Runnable和Callable。
ExecutorService :对Excetor进行扩展,提供了Future异步支持(任务提交后在需要时检查 Future是否有结果,其get() 方法是阻塞式的,如果调用时任务还没有完成,会等待直到任务执行结束)。
接口源码如下:
//顶层接口 public interface Executor { //执行任务 void execute(Runnable command); }
//线程池接口 public interface ExecutorService extends Executor { //关闭线程池,不再接受新任务,等待所有任务完成 void shutdown(); //关闭线程池,不再接受新任务,返回等待执行的任务列表 List<Runnable> shutdownNow(); //线程池是否关闭 boolean isShutdown(); //线程池关闭,所有任务均完成则返回true boolean isTerminated(); //阻塞,直到所有线程执行完毕或者超时 boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; //提交一个任务,交给线程池执行(callable自带返回结果) <T> Future<T> submit(Callable<T> task); //提交一个任务,交给线程池执行(runnable不自带返回结果,用result表示) <T> Future<T> submit(Runnable task, T result); //提交一个任务交给线程池执行,并返回该任务的future Future<?> submit(Runnable task); //执行给定任务集合(可指定超时时间),全部完成(未抛出异常),返回future集合 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException; //执行给定任务(可指定超时时间),完成(未抛出异常),返回future <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
2.AbstractExecutorService
首先简单看一下任务相关的接口和实现类。
Future接口:用来实现异步任务获取任务结果。Callable任务返回Future对象。源码如下:
public interface Future<V> { //尝试取消任务 boolean cancel(boolean mayInterruptIfRunning); //如果任务正常完成前被取消,则返回true boolean isCancelled(); //如果任务完成,则返回true boolean isDone(); //查询结果(一直阻塞到任务返回结果) V get() throws InterruptedException, ExecutionException; //查询结果(一直阻塞到指定时间) V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException; }
Runnable接口:用来创建任务。源码如下:
public interface Runnable { //任务执行体 public abstract void run(); }
RunnableFuture接口:Future和Runnable的子接口。任务的创建、异步支持。源码如下:
public interface RunnableFuture<V> extends Runnable, Future<V> { //任务执行体 void run(); }
FutureTask类:RunnableFuture的接口实现类。是一个支持取消的异步任务执行器,支持Callable或者Runnable类型任务的执行。源码后续单独分析。
AbstractExecutorService给出ExecutorService的一个抽象实现。用于异步任务、任务执行的调度管理等。依次分析相关方法。
创建任务,使用任务来构造FutureTask并返回,源码如下:
//创建任务 protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { //构造器中value用来保存任务返回结果 return new FutureTask<T>(runnable, value); } protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); }
提交任务,就是调用execute(),传入任务进行执行,这里交给子类实现。源码如下:
//提交任务 public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); //抽象类没有实现execute(),这里交给子类实现 execute(ftask); return ftask; } public <T> Future<T> submit(Runnable task, T result) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task, result); execute(ftask); return ftask; } public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
执行给定任务集合,返回一个已经成功完成的任务的结果(任务得到结果、没有抛出异常视为执行成功)。源码如下:
//执行任务集合,返回第一个执行成功的结果 private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,boolean timed, long nanos) throws InterruptedException, ExecutionException, TimeoutException { if (tasks == null) throw new NullPointerException(); int ntasks = tasks.size(); if (ntasks == 0) throw new IllegalArgumentException(); //构造futures集合 ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks); //ExecutorCompletionService可以使用阻塞队列来保存多个线程的执行结果(future类型) ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this); try { ExecutionException ee = null; //超时时间的nanos表示 final long deadline = timed ? System.nanoTime() + nanos : 0L; Iterator<? extends Callable<T>> it = tasks.iterator(); //ExecutorCompletionService提交任务返回future,然后添加到集合中 futures.add(ecs.submit(it.next())); --ntasks; int active = 1; for (;;) { //轮询队列中已经完成的任务,弹出其future然后从队列中删除 Future<T> f = ecs.poll(); //future为空,调用阻塞队列的take获取对应线程的执行结果 if (f == null) { if (ntasks > 0) { --ntasks; futures.add(ecs.submit(it.next())); ++active; } else if (active == 0) break; else if (timed) { f = ecs.poll(nanos, TimeUnit.NANOSECONDS); if (f == null) throw new TimeoutException(); nanos = deadline - System.nanoTime(); } else f = ecs.take(); } //future不为空,get其结果 if (f != null) { --active; try { return f.get(); } catch (ExecutionException eex) { ee = eex; } catch (RuntimeException rex) { ee = new ExecutionException(rex); } } } if (ee == null) ee = new ExecutionException(); throw ee; } finally { for (int i = 0, size = futures.size(); i < size; i++) futures.get(i).cancel(true); } } //执行任务集合,返回一个已经成功任务的结果(支持超时时间) public <T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { //doInvokeAny() return doInvokeAny(tasks, true, unit.toNanos(timeout)); } public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException { try { //doInvokeAny() return doInvokeAny(tasks, false, 0); } catch (TimeoutException cannotHappen) { assert false; return null; } }
执行给定任务,所有任务成功完成()则返回其future集合。源码如下:
//执行任务集合,返回任务的Future集合(支持超时时间) public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException { if (tasks == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); //构造future集合 ArrayList<Future<T>> futures = new ArrayList<Future<T>>(tasks.size()); boolean done = false; try { for (Callable<T> t : tasks) //newTaskFor()将Callable类型转化为FutureTask类型,并添加到futures集合中 futures.add(newTaskFor(t)); final long deadline = System.nanoTime() + nanos; final int size = futures.size(); //执行所有任务 for (int i = 0; i < size; i++) { //这里调用execute() execute((Runnable)futures.get(i)); nanos = deadline - System.nanoTime(); if (nanos <= 0L) return futures; } //调用所有future的get,阻塞获取任务结果 for (int i = 0; i < size; i++) { Future<T> f = futures.get(i); if (!f.isDone()) { if (nanos <= 0L) return futures; try { //FutureTask调用get获取任务结果 f.get(nanos, TimeUnit.NANOSECONDS); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } catch (TimeoutException toe) { return futures; } nanos = deadline - System.nanoTime(); } } done = true; return futures; } finally { if (!done) for (int i = 0, size = futures.size(); i < size; i++) futures.get(i).cancel(true); } } public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException { if (tasks == null) throw new NullPointerException(); ArrayList<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 (int i = 0, size = futures.size(); i < size; i++) { Future<T> f = futures.get(i); if (!f.isDone()) { try { f.get(); } catch (CancellationException ignore) { } catch (ExecutionException ignore) { } } } done = true; return futures; } finally { if (!done) for (int i = 0, size = futures.size(); i < size; i++) futures.get(i).cancel(true); } } }
3.ThreadPoolExecutor
一般线程池包含三部分:调度器、线程队列、任务队列。其中调度器将任务队列中的任务分配给线程队列中的线程去执行,执行完毕之后线程又会到线程队列中。
ThreadPoolExecutor是AbstractExecutorService的直接子类。提供了最基础的线程池功能。ThreadPoolExecutor就没有调度器,线程队列中的所有线程自动去获取任务队列中的任务进行执行。可见核心其实就是自动控制线程队列长度与任务队列长度相匹配,从而使任务按顺序合理执行。其中线程队列存放当前正在处理任务的线程或者空闲线程,任务队列存放待执行任务(正在被线程执行的任务是不在任务队列中的)。
使用corePoolSize(合理容量)、maximumPoolSize(最大容量)来控制线程队列的长度,每当调用execute(Runnable)提交新任务到线程池中会自动调整线程个数,就是如果来了新任务,线程优先增长到合理的个数,之后再来新任务则优先加入任务队列,任务队列放不下则线程个数增长到最大个数。如下:
如果还没超过合理容量:则需要新建线程来处理新任务
如果超过最合理容量且小于最大容量:任务队列未满则新任务放到任务队列中,任务队列满了则新建线程来处理新任务
如果等于最大容量:任务队列未满则新任务放到任务队列中,任务队列满了则执行拒绝策略(RejectedExecutionHandler )