1、Executor和ExecutorService
基于生产者——消费者模式,提交任务的线程是生产者,执行的是消费者。
public interface Executor {
void execute(Runnable command);
}
为了解决执行服务的生命周期问题,有了ExecutorService接口,添加了一些用于生命周期管理的方法。线程池有RUNNING、SHUTDOWN(调用shutDown())、STOP(调用shutDownNow()),TERMINATED(销毁线程、清空队列)四种状态。
public interface ExecutorService extends Executor {
// 平稳关闭,不再接受新任务,等待已提交的任务执行完成,包括那些还未开始执行的任务
void shutdown();
// 停止正在执行的任务,取消等待中的任务,返回等待执行的任务的List
List<Runnable> shutdownNow();
// 当调用shutdown()方法后返回为true。
boolean isShutdown();
// 当调用shutdown()方法后,并且所有提交的任务完成后返回为true
boolean isTerminated();
/**
* 调用此方法,在shutdown请求发起后,除非以下任何一种情况发生,否则当前线程将一直到阻塞。
* 1、所有任务执行完成
* 2、超过超时时间
* 3、当前线程被中断
*/
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
// 提交一个带有返回值的任务(Callable),返回值为Future,表示了任务的执行完成结果,Future.get()方法返回成功执行后的结果。
<T> Future<T> submit(Callable<T> task);
// 提交一个Runnable任务执行,返回一个Future做为任务task的代理,Future.get()方法在执行成功后可以返回result。
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
// 执行一组任务,返回一个Future的list,其中的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;
// 执行一组任务,当成功执行完一个任务(没有抛异常),就返回结果,不论正常返回还是异常结束,未执行的任务都会被取消。
<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、Executors
返回ExecutorService的工厂类,返回不同的线程池,都利用了ThreadPoolExecutor类,ThreadPoolExecutor构造器有如下几个参数
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:核心池大小。创建线程池后, 线程池中没有线程,任务来了再创建线程,线程数达到corePoolSize后,任务放进阻塞队列workQueue;
maximumPoolSize:最大线程数。只有当workQueue已满时,线程池才会创建新线程,直到线程数达到maximumPoolSize;
keepAliveTime,unit:当线程数大于corePoolSize且线程的空闲时间大于keepAliveTime,销毁该线程,如果allowCoreThreadTimeout设置为true,则所有线程均会退出直到线程数量为0;
workQueue:存储等待执行任务的队列,当线程数量达到corePoolSize时,新到达的任务放入该阻塞队列,如果阻塞队列满了,则创建新的线程;
threadFactory:线程工厂;
handler:表示拒绝处理任务时的策略,当workQueue已满且线程数达到maximumPoolSize时调用。有【1】丢弃任务并抛出RejectedExecutionException异常(AbortPolicy,默认的)【2】丢弃任务,不抛出异常(DiscardPolicy)【3】丢弃任务队列最前面的任务,然后尝试重新提交新的任务(DiscardOldestPolicy,不适合与优先级队列一起使用)【4】由调用线程处理该任务(CallerRunsPolicy);等四种策略。
// 节选自jdk1.8
public class Executors {
/**
* corePoolSize = maximumPoolSize =nThreads
* 默认使用无界的LinkedBlockingQueue
* keepAliveTime为0,线程空闲即销毁(线程数大于corePoolSize且队列里无任务)
* 未指定threadFactory和handler,则使用默认的,分别为Executors的内部类DefaultThreadFactory,AbortPolicy
*/
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
// 创建一个带并行级别的线程池,并行级别决定了同一时刻最多有多少个线程在执行,如不穿如并行级别参数,将默认为当前系统的CPU个数
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool(parallelism, ForkJoinPool.defaultForkJoinWorkerThreadFactory, null, true);
}
// 和newFixedThreadPool一样,只是corePoolSize = maximumPoolSize = 1
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
}
/** corePoolSize = 0,maximumPoolSize = Integer.MAX_VALUE
* keepAliveTime = 1 min
* 要将元素放入SynchronousQueue中,必须有另一个线程在等待接受这个元素,否则创建新线程
* */
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
// 创建一个定长线程池,支持定时及周期性任务执行,使用DelayQueue,只有元素逾期后,才能take(),元素根据逾期时间排序
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
}
}
3、Callable、Future、FutureTask
(1)Callable有返回值,可以抛出RuntimeException,Runnable无返回值,不可以抛出异常(没有返回值,没有其它线程处理异常)
(2)Future表示任务的生命周期,ExecutorService中的submit()返回Future,任务未完成get()会阻塞,get()可以指定时间
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
(3)FutureTask,可以执行多任务计算,可以在高并发环境下保证任务只执行一次。有等待运行、正在运行、运行完成三种状态,完成状态包括因取消或异常结束,完成后停止在这个状态上。
完成后get()立即返回,否则阻塞。完成后返回结果或者抛出异常,FutureTask将计算结果从计算线程传递到get()的线程。
// 节选了jdk1.8的get()方法,RunnableFuture extends Runnable, Future
public class FutureTask<V> implements RunnableFuture<V> {
// 各种状态值,以前用AQS实现,状态用AQS里的state表示
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
private int awaitDone(boolean timed, long nanos) throws InterruptedException {
final long deadline = timed ? System.nanoTime() + nanos : 0L;
WaitNode q = null;
boolean queued = false;
for (;;) {
if (Thread.interrupted()) {
removeWaiter(q);
throw new InterruptedException();
}
int s = state;
// 完成返回
if (s > COMPLETING) {
if (q != null)
q.thread = null;
return s;
// 未完成则让步
} else if (s == COMPLETING)
Thread.yield();
else if (q == null)
q = new WaitNode();
else if (!queued)
queued = UNSAFE.compareAndSwapObject(this, waitersOffset, q.next = waiters, q);
else if (timed) {
nanos = deadline - System.nanoTime();
if (nanos <= 0L) {
removeWaiter(q);
return state;
}
LockSupport.parkNanos(this, nanos);
} else
LockSupport.park(this);
}
}
}