欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ExecutorService使用笔记

程序员文章站 2022-03-24 12:37:12
...

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,将在超时后返回线程池是否已经关闭。