ExecutorService
ExecutorService 是用来可以控制与管理多个异步任务的东西,可以结束异步任务的结束,以及
用于跟踪查看多个异步任务的当前情况。
一般使用如下:
ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.submit(new ThreadRunnable());
executorService.shutdown();
除了newFixedThreadPool,还有其他几个,如下描述:
1. newSingleThreadExecutor
线程池只运行单线程,每个提交的任务都会按照提交的顺序依次执行。如果线程是由于内部原因不是因为调用
了shutdown导致的启动失败,新的线程会重新创建代替原理的线程。
2. newCachedThreadPool
提交一个任务,如果线池里面有空闲线程,将使用空闲线程执行任务,如果没有空闲可用线程,将
创建新的线程。比较适合工作时间比较短的异步任务,提高利用效率。如果一个线程空闲时间超过
60秒,会自动结束回收线程。
3. newFixedThreadPool(int nThreadsNum)
线程池将限制线程数量最多为nThreadsNum,当提交一个任务,会等待线程池里面的线程有空闲了
才会执行。
4. newScheduledThreadPool(int corePoolSize)
线程池将限制线程数量为corePoolSize即便线程都在空闲状态。返回的是ScheduledExecutorService,
可以定时周期的执行任务。
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
executorService.schedule(new Runnable() {
@Override
public void run() {
Logger.l("5秒后执行到这里");
}
},5,TimeUnit.SECONDS);
executorService.shutdown();
ExecutorService的关闭有两个,一个是shutdownNow,一个是shutdown。shutdown执行后
将禁止提交任务到线程池去,就是说除了已经提交进去的,shutdown后不再接受其他的提交任务。
同时如果shutdown后执行提交,将抛出RejectedExecutionException,但是正在执行的线程是不会
被终止的,如下:
public class ThreadRunnable implements Runnable {
private final SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss.SSS");
private Integer num;
public ThreadRunnable(Integer num) {
this.num = num;
}
@Override
public void run() {
System.out.println("thread:" + Thread.currentThread().getName() + ",time:" + format.format(new Date()) + ",num:" + num);
try {//使线程睡眠,模拟线程阻塞情况
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread:" + Thread.currentThread().getName() + "is completed,"+num );
}
ExecutorService executorService = Executors.newFixedThreadPool(2);
for(int i=0;i<10;i++){
executorService.submit(new ThreadRunnable(i));
if(i==3){
executorService.shutdown();
}
}
打印结果:
thread:pool-1-thread-2,time:16:40:34.385,num:1
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at com.example.netty.ThreadExecutor.main(ThreadExecutor.java:13)
thread:pool-1-thread-2is completed,1
thread:pool-1-thread-1is completed,0
thread:pool-1-thread-2,time:16:40:35.385,num:2
thread:pool-1-thread-1,time:16:40:35.385,num:3
thread:pool-1-thread-1is completed,3
thread:pool-1-thread-2is completed,2
如果使用shutdownNow,线程池将关闭同时终止调当前正在执行的线程。如果有线程正在执行,
也会抛出RejectedExecutionException,同时终止调该线程,注意与shutdown的区别。
除了它们外,还可以通过future进行关闭等控制:
final Future<?> future = executorService.submit(new ThreadRunnable(1));
future.cancel(true);
5.awaitTermination(long timeout, TimeUnit unit):
调用该方法后将等待线程池关闭,如果等待时间超时,超过timeout,将在超时后返回线程池是否已经关闭。