#什么是线程池?
线程池是一种多线程处理形式,java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于创建线程池。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
Executor接口里面只有一个回调方法execute(Runnable command):
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* @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);
}
接口ExecutorService,给出一系列方法,例如shutdown,可以实时关闭Excutor执行等。另外还可以通过Future类来跟随判断当前执行任务的状态。还有submit方法用来提交执行的新任务,并且Future通过ExcutorService里面的submit方法来返回得到。
抽象类AbstractExecutorService实现了ExecutorService里面一些功能。比如submit():
/**
* Returns a {@code RunnableFuture} for the given runnable and default
* value.
*
* @param runnable the runnable task being wrapped
* @param value the default value for the returned future
* @param the type of the given value
* @return a {@code RunnableFuture} which, when run, will run the
* underlying runnable and which, as a {@code Future}, will yield
* the given value as its result and provide for cancellation of
* the underlying task
* @since 1.6
*/
protected RunnableFuture newTaskFor(Runnable runnable, T value) {
return new FutureTask(runnable, value);
}
/**
* Returns a {@code RunnableFuture} for the given callable task.
*
* @param callable the callable task being wrapped
* @param the type of the callable's result
* @return a {@code RunnableFuture} which, when run, will call the
* underlying callable and which, as a {@code Future}, will yield
* the callable's result as its result and provide for
* cancellation of the underlying task
* @since 1.6
*/
protected RunnableFuture newTaskFor(Callable callable) {
return new FutureTask(callable);
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public Future submit(Callable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
可以看出来上面的返回值是一个FutureTask。FutureTask是对Future接口的间接实现。中间有个Runnable接口。在这里就不在多说知道它的功能即可(用来追踪Task任务的执行状态)。
最后的线程维护各种东西都是在ThreadPoolExecutor这个类里面进行的。
下面是ThreadPoolExecutor最核心的构造方法:
参数名 | 作用 |
---|---|
corePoolSize | 核心线程池大小 |
maximumPoolSize | 最大线程池大小 |
keepAliveTime | 线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使得核心线程有效时间 |
TimeUnit | keepAliveTime时间单位 |
workQueue | 阻塞任务队列 |
threadFactory | 新建线程工厂 |
RejectedExecutionHandler | 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理 |
1.当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
2.当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
3.当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
4.当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
5.当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
6.当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭
ExecutorService es = Executors.newCachedThreadPool();
ExecutorService es = Executors.newFixedThreadPool(2);
ExecutorService es = Executors.newSingleThreadExecutor();
ScheduledExecutorService es = Executors.newScheduledThreadPool(2);
以上Executors利用工厂模式向我们提供了4种线程池实现方式,但是并不推荐使用,原因是使用Executors创建线程池不会传入这个参数而使用默认值所以我们常常忽略这一参数,而且默认使用的参数会导致资源浪费,不可取。最好通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
ThreadPoolExecutor cachedThreadPool = new ThreadPoolExecutor(
0,
Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue(),
new ThreadPoolExecutor.AbortPolicy());
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
}
});
cachedThreadPool.shutdown();
ThreadPoolExecutor singleThreadPool = new ThreadPoolExecutor(
2,
2,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
new ThreadPoolExecutor.AbortPolicy());
singleThreadPool.execute(new
Runnable() {
@Override
public void run () {
}
});
singleThreadPool.shutdown();
ThreadPoolExecutor singleThreadPool = new ThreadPoolExecutor(
1,
1,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
new ThreadPoolExecutor.AbortPolicy());
singleThreadPool.execute(new Runnable() {
@Override
public void run() {
}
});
singleThreadPool.shutdown();
// 延时任务
executorService1.schedule(new TimerTask() {
@Override
public void run() {
finish();
startActivity(new Intent(WelcomeUI.this, TabUI.class));
}
},1, TimeUnit.SECONDS);
executorService1.shutdown();
ScheduledExecutorService executorService2 = new ScheduledThreadPoolExecutor(1,new ThreadPoolExecutor.AbortPolicy());
// 从0秒开始每隔2秒执行一次
executorService2.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
finish();
startActivity(new Intent(WelcomeUI.this, TabUI.class));
}
},0, 2,TimeUnit.SECONDS);
executorService2.shutdown();
ScheduledExecutorService executorService3 = new ScheduledThreadPoolExecutor(1,new ThreadPoolExecutor.AbortPolicy());
// 延迟5秒间隔3秒执行(第一次间隔8秒,之后3秒执行一次,但是间隔3秒后会检测上一个任务是否执行完毕如果没有会等待执行完毕后执行)
executorService3.scheduleWithFixedDelay (new TimerTask() {
@Override
public void run() {
finish();
startActivity(new Intent(WelcomeUI.this, TabUI.class));
}
},5, 3,TimeUnit.SECONDS);
executorService3.shutdown();