ScheduledThreadPool

2,012 阅读4分钟

创建ScheduleThreadPool

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);

这里还是选择自动创建的,参数是 corePoolSize即5个,下面看怎么自动创建

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }

从源码可以看出,它创建线程池,是调用了父类的构造方法,如下

public class ScheduledThreadPoolExecutor
        extends ThreadPoolExecutor
        implements ScheduledExecutorService

继承了 ThreadPoolExecutor,所以创建 ScheduledThreadExecutor 本质也是创建一个 ThreadPoolExecutor 线程池,只是传入的参数不相同,那么 ScheduledThreadExecutor 的方法传入了哪些参数?

  • 第一个参数位置,是 corePoolSIze,也就是5个核心线程数
  • 第二个参数位置,是 maximumPoolSize,也就是Integer.MAX_VALUE,代表了理论可以创建的线程最大的个数
  • 第三个参数位置,是KeepAliveTime,也就是空闲线程存活的时间,既然是零,也就是线程池空闲的时候,会把线程直接销毁
  • 第四个参数位置,是 unit,居然是NANOSECONDS,反正是前面的 KeepAliveTime是0了, 是纳秒还是毫秒,好像差不多的样子
  • 第五个参数位置,是 Handler,是DelayedWorkQueue,一个延迟队列,也就是按一定的时间执行任务,或者每隔一段时间执行一次任务

ScheduleThreadPool的使用

ScheduledThreadPool.shedule(Runnable command,long delay, TimeUnit unit)

public class TestScheduledThreadPool {

    public static void main(String[] args) {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "进来了," +
                        "当前时间是 " + LocalDateTime.now());
            }
        });

       for (int i = 0; i < 10; ++i) {
            try {
                threadPool.schedule(thread, 5l, TimeUnit.SECONDS);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        threadPool.shutdown();
    }
}

在这里插入图片描述

第一个参数是传入任务,也就是你要执行的任务 第二个参数是延迟多长时间后执行任务 第三个参数是延迟的时间单位是什么,我上面用的是秒

我在上面还让线程执行一次任务后,睡眠一秒,然后再提交一次任务,不出所料,每次提交任务后,都是隔5秒去执行

也就是调用 shedule(Runnable command,long delay, TimeUnit unit)方法,是规定让线程池延迟多久去执行任务

scheduleAtFixedRate(Runnable command,long initialDelay, long period,TimeUnit unit)

public class TestScheduledThreadPool {

    public static void main(String[] args) {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "进来了," +
                        "当前时间是 " + LocalDateTime.now());
            }
        });

        threadPool.scheduleAtFixedRate(thread, 5l, 2l, TimeUnit.SECONDS);
    }
}

在这里插入图片描述

第一个参数是你要提交的任务 第二个参数是你初始化后多少秒开始执行第一个任务(只在初始化有用) 第三个参数是 period,也就是周期,单位是long,你设置多少就是每隔多少时间 第四个参数是时间单位,为前面第二、三个参数的时间单位,我这里的是秒

如打印的时间内容来看,确实是每隔2秒去执行一次任务(貌似是重复执行这个任务),而且不会停止(我后面没有调用 shutdown()方法)

也就是 scheduleAtFixedRate(Runnable command,long initialDelay, long period,TimeUnit unit) 是经过初试时间后,每调用一次任务开始就计时,无论这个任务是否结束,都会倒计时后去执行新的任务

  • 调用任务,初试时间为5,周期为2,即 0:00
  • 0:05开始第一次任务
  • 0:07开始第二次任务
  • 0:09开始第二次任务
  • ...

scheduleWithFixedDelay(Runnable command,ong initialDelay,long delay,TimeUnit unit);

public class TestScheduledThreadPool {

    public static void main(String[] args) {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                    System.out.println(Thread.currentThread().getName() + "进来了," +
                            "当前时间是 " + LocalDateTime.now());
            }
        });

        threadPool.scheduleWithFixedDelay(thread, 5l, 4l, TimeUnit.SECONDS);

    }
}

在这里插入图片描述

这些参数的含义跟上面的那个 ScheduledAtFixedRate(...)的一样 甚至打印出来的时间看起来也差不多,没有什么差别,其实不是的,是我的任务要执行的内容太少了,所以显示不出差别,下面给大家说说差别

  • 调用任务,初试时间为5,周期为4,即 0:00
  • 开始第一次任务的时间为 0:05,任务结束的时间为 0:08(随便写的)
  • 第二次开始任务的时间为0:12,任务结束的时间为0:17(随便写的)
  • 第三次任务开始的时间为0:21,任务结束的时间为0:24(随便写的)
  • ... 也就是它的周期是以前一个线程结束后,开始倒计时的

submit(Runnable task)

public class TestScheduledThreadPool {

    public static void main(String[] args) {
        ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                System.out.println(Thread.currentThread().getName() + "进来了," +
                        "当前时间是 " + LocalDateTime.now());
            }
        });

        for (int i = 0; i < 10; ++i) {
            threadPool.submit(thread);
        }

        threadPool.shutdown();
    }
}

与其它线程池,在submit()这里,好像没什么不同,都是直接提交任务,当然从源码角度可以看出,写的代码是不一样的

public Future<?> submit(Runnable task) {
        return schedule(task, 0, NANOSECONDS);
    }

第二个参数是延迟,也就是0,就是提交了任务,不需要延迟等待多少秒,就执行它


欢迎大家关注下个人的「公众号」:独醉贪欢