java中常见的六种线程池详解 (2)

这里我们需要注意点,它使用了 SynchronousQueue 的一个阻塞队列来存储任务,这个队列是无法存储的,因为他的容量为0,它只负责对任务的传递和中转,效率会更高,因为核心线程都为0,这个队列如果存储任务不存在意义。

ScheduledThreadPool

ScheduledThreadPool 线程池是支持定时或者周期性执行任务,他的创建代码 Executors.newSchedsuledThreadPool(int) 中,如下所示:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public static ScheduledExecutorService newScheduledThreadPool( int corePoolSize, ThreadFactory threadFactory) { return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); }

我们发现这里调用了 ScheduledThreadPoolExecutor 这个类的构造函数,进一步查看发现 ScheduledThreadPoolExecutor 类是一个继承了 ThreadPoolExecutor 的,同时实现了 ScheduledExecutorService 接口,我们看到它的几个构造函数都是调用父类 ThreadPoolExecutor 的构造函数

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

从上面代码我们可以看到和其他线程池创建并没有差异,只是这里的任务队列是 DelayedWorkQueue 关于阻塞丢列我们下篇文章专门说,这里我们先创建一个周期性的线程池来看一下

public static void main(String[] args) { ScheduledExecutorService service = Executors.newScheduledThreadPool(5); // 1. 延迟一定时间执行一次 service.schedule(() ->{ System.out.println("schedule ==> 云栖简码-i-code.online"); },2, TimeUnit.SECONDS); // 2. 按照固定频率周期执行 service.scheduleAtFixedRate(() ->{ System.out.println("scheduleAtFixedRate ==> 云栖简码-i-code.online"); },2,3,TimeUnit.SECONDS); //3. 按照固定频率周期执行 service.scheduleWithFixedDelay(() -> { System.out.println("scheduleWithFixedDelay ==> 云栖简码-i-code.online"); },2,5,TimeUnit.SECONDS); }

上面代码是我们简单创建了 newScheduledThreadPool ,同时演示了里面的三个核心方法,首先看执行的结果:

java中常见的六种线程池详解

首先我们看第一个方法 schedule , 它有三个参数,第一个参数是线程任务,第二个delay 表示任务执行延迟时长,第三个unit 表示延迟时间的单位,如上面代码所示就是延迟两秒后执行任务

public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);

第二个方法是 scheduleAtFixedRate 如下, 它有四个参数,command 参数表示执行的线程任务 ,initialDelay 参数表示第一次执行的延迟时间,period 参数表示第一次执行之后按照多久一次的频率来执行,最后一个参数是时间单位。如上面案例代码所示,表示两秒后执行第一次,之后按每隔三秒执行一次

public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

第三个方法是 scheduleWithFixedDelay 如下,它与上面方法是非常类似的,也是周期性定时执行, 参数含义和上面方法一致。这个方法和 scheduleAtFixedRate 的区别主要在于时间的起点计时不同

public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);

scheduleAtFixedRate 是以任务开始的时间为时间起点来计时,时间到就执行第二次任务,与任务执行所花费的时间无关;而 scheduleWithFixedDelay 是以任务执行结束的时间点作为计时的开始。如下所示

java中常见的六种线程池详解

SingleThreadScheduledExecutor

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpszsd.html