线程池
任务放在队列中,队列交给线程。
start()和run()区别:
start()
是线程的启动方法,线程被CPU调度,并发执行。
public synchronized void start() {
if (threadStatus != 0) //判断是否是就绪状态
throw new IllegalThreadStateException();
group.add(this); //加入线程组
boolean started = false;
try {
start0(); //启动线程
started = true; //可运行状态
} finally {
try {
if (!started) {
//线程启动失败,移除当前线程,同时nUnstartedThreads++;
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
run()
只是线程的一个普通方法,顺序执行。
@Override
public void run() {
if (target != null) { //判断线程是否存在
target.run();
}
}
java中的几个多线程的类。
1、Executor
Executor:一个接口,其定义了一个接受Runnable对象的方法execute,其方法签名为execute(Runnable command)。
public interface Executor {
void execute(Runnable command);
}
Executor(执行器),只需要把Runnable任务放到执行器的execute方法中就代表提交任务了,具体怎么分配线程和执行就不用管了。这个操作把任务的提交和执行解耦了。每一个任务提交会创建一个线程,直到达到阈值。下面是使用方法:
public void execute(List<Runnable> runnables) {
//创建包含10个线程的执行器
Executor executor = Executors.newFixedThreadPool(10);
for (Runnable r : runnables) {
//提交任务
executor.execute(r);
}
}
其中的Executors类提供了一系列创建Executor子类的静态方法(最主要有四类)。也可以通过继承Executors类,自定义执行器。
public class CustomExecutor implements Executor {
@Override
public void execute(Runnable r){
/* 在这里自定义执行方式*/
r.run();
}
}
2、ExecutorService
ExecutorService:是一个比Executor使用更广泛的子类接口,其提供了生命周期管理的方法,以及可以跟踪一个或多个异步执行状况返回Fture的方法。(Fture接口提供了检查计算是否完成的方法,常用的FtureTask实现了Fture接口和Runable接口,可以由Executor执行。)
public interface ExecutorService extends Executor {
/**
* 启动有序关闭,其中已经提交的任务会执行,但不会接受任何新任务。
*/
void shutdown();
/**
* 尝试停止所有主动执行的任务,停止等待任务的处理,并返回正在等待执行
* 的任务列表。
*/
List<Runnable> shutdownNow();
/**
* 判断执行者是否关闭。
*/
boolean isShutdown();
/**
* 判断所有任务在关闭后是否完成。
*/
boolean isTerminated();
/**
* 主线程等待线程池所有线程执行完毕后再执行
* @param timeout 最长等待时间
* @param unit 时间的单位
* @return {@code true} 等到指定时间,线程池中线程运行完毕
* {@code false} 等到指定时间,线程池中线程未运行完毕
* @throws InterruptedException if interrupted while waiting
*/
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);
}
3、AbstractExecutorService
AbstractExecutorService:ExecutroService执行方法的默认实现类,提供模板方法,定义方法的算法骨架,使用了设计模式的模板方法模式。
/**
* @param Runable任务
* @return Future对象
*/
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
/**
* @param Runable任务
* @param 结果返回
* @return Future对象
*/
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;
}
/**
* @param Callable任务
* @return Future对象
*/
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
4、ScheduledExecutorService
ScheduledExecutorService:一个可定时调度任务的接口。
public interface ScheduledExecutorService extends ExecutorService {
/**
* 延时指定时间后执行任务
* @param command 要执行的任务
* @param delay 延迟执行的时间
* @param unit 时间的单位
*/
public ScheduledFuture<?> schedule(Runnable command,
long delay, TimeUnit unit);
/**
* 延时指定时间后执行任务
* @param command 要执行的任务
* @param delay 延迟执行的时间
* @param unit 时间的单位
*/
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay, TimeUnit unit);
/**
* 在指定时间后开始执行一个任务,之后不管任务是否执行完,每隔一段时间都
* 开启一次新任务,如果此任务的任何一个执行要花费比其周期更长的时间,则
* 将推迟后续执行,但不会同时执行
* @param command 要执行的任务
* @param initialDelay 首次执行的延迟时间
* @param period 连续执行时间周期
* @param unit 时间的单位
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
/**
* 在指定时间后开始执行一个任务,之后在一个任务执行完之后,隔指定时间周期
* 后开启另一个任务。
* @param command 要执行的任务
* @param initialDelay 首次执行的延迟时间
* @param period 连续执行时间周期
* @param unit 时间的单位
*/
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
}
5、ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor:ScheduledExecutorService的实现类,一个可定时调度任务的线程池。
通过以下方式实现延时和定时:
/**
* 延时指定时间后执行任务
* @param command 要执行的任务
* @param delay 延迟执行的时间
* @param unit 时间的单位
*/
public ScheduledFuture<?> schedule(Runnable command,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Void>(command, null,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}
/**
* 延时指定时间后执行任务
* @param command 要执行的任务
* @param delay 延迟执行的时间
* @param unit 时间的单位
*/
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay,
TimeUnit unit) {
if (callable == null || unit == null)
throw new NullPointerException();
RunnableScheduledFuture<V> t = decorateTask(callable,
new ScheduledFutureTask<V>(callable,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}
/**
* 在指定时间后开始执行一个任务,之后不管任务是否执行完,每隔一段时间都
* 开启一次新任务,如果此任务的任何一个执行要花费比其周期更长的时间,则
* 将推迟后续执行,但不会同时执行
* @param command 要执行的任务
* @param initialDelay 首次执行的延迟时间
* @param period 连续执行时间周期
* @param unit 时间的单位
*/
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(period));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
/**
* 在指定时间后开始执行一个任务,之后在一个任务执行完之后,隔指定时间周期
* 后开启另一个任务。
* @param command 要执行的任务
* @param initialDelay 首次执行的延迟时间
* @param period 连续执行时间周期
* @param unit 时间的单位
*/
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (delay <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(-delay));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
6、ThreadPoolExecutor
ThreadPoolExecutor:线程池,可以通过调用Executors以下静态工程方法来创建线程池并返回一个ExecutorService对象。
/**
* @param corePoolSize 核心线程池大小
* @param maximumPoolSize 线程池最大容量
* @param keepAliveTime 线程池空闲时,线程存活的时间
* @param unit 单位
* @param workQueue 工作队列
* @param threadFactory 线程工厂
* @param handler 处理当线程队列满了,也就是执行拒绝策略
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
多线程创建的工厂类Executors
newFixedThreadPool(int nThreads)
创建一个拥有固定线程数量的线程池,具体的线程数量由nThreads参数指定。最开始该线程池中的线程数为0,之后每提交一个任务就会创建一个线程,直到线程数等于指定的nThreads参数,此后线程数量将不再变化。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newCachedThreadPool()
创建一个可缓存的线程池。会为每个任务都分配一个线程,但是如果一个线程执行完任务后长时间(60秒)没有新的任务可执行,该线程将被回收。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
newSingleThreadExecutor()
创建单线程的线程池。其实只有一个线程,被提交到该线程的任务将在一个线程中串行执行,并且能确保任务可以按照队列中的顺序串行执行。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newScheduledThreadPool(int corePoolSize)
创建固定线程数量的线程池,而且以延迟或定时的方式来执行任务。
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}