创建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,就是提交了任务,不需要延迟等待多少秒,就执行它
欢迎大家关注下个人的「公众号」:独醉贪欢