2018年7月9日08:48:58
欢迎扫二维码关注公众号,获取技术干货
【1】前言
线程池与任务定时执行,一是项目随处可见的一种技术,二是自己还需打打扎实基础;不可以仅仅局限于业务的实现,要去体会底层的思想;
【2】关于线程池ThreadPoor与Timer的使用
2.1 Java提供的Time类可以周期性地或者延期执行任务,但是有时我们需要并行执行同样的任务,这个时候如果创建多个Time对象会给系统带来负担,解决办法是将定时任务放到线程池中执行。
Java的ScheduledThreadPoolExecutor类实现了ScheduledExecutorService接口中定义的以不同方法执行任务的方法。
2.2 ScheduleThreadPoolExecutor与Timer相比的优势
(1)Timer是基于绝对时间的延时执行或周期执行,当系统时间改变,则任务的执行会受到的影响。而ScheduleThreadPoolExecutore中,任务时基于相对时间进行周期或延时操作。
(2)Timer也可以提交多个TimeTask任务,但只有一个线程来执行所有的TimeTask,这样并发性受到影响。而ScheduleThreadPoolExecutore可以设定池中线程的数量。
(3)Timer不会捕获TimerTask的异常,只是简单地停止,这样势必会影响其他TimeTask的执行。而ScheduleThreadPoolExecutore中,如果一个线程因某些原因停止,线程池可以自动创建新的线程来维护池中线程的数量。
2.3 自jdk1.5开始,Java开始提供ScheduledThreadPoolExecutor类来支持周期性任务的调度,在这之前,这些工作需要依靠Timer/TimerTask或者其它第三方工具来完成。但Timer有着不少缺陷,如Timer是单线程模式,调度多个周期性任务时,如果某个任务耗时较久就会影响其它任务的调度;如果某个任务出现异常而没有被catch则可能导致唯一的线程死掉而所有任务都不会再被调度。ScheduledThreadPoolExecutor解决了很多Timer存在的缺陷。JDK1.5之前的Timer和TimerTask类已经过时了。
通过如上的介绍,可以对比一下Timer和ScheduledThreadPoolExecutor:
Timer | ScheduledThreadPoolExecutor |
单线程 | 多线程 |
单个任务执行时间影响其他任务调度 | 多线程,不会影响 |
基于绝对时间 | 基于相对时间 |
一旦执行任务出现异常不会捕获,其他任务得不到执行 | 多线程,单个任务的执行不会影响其他线程 |
所以,在JDK1.5之后,应该没什么理由继续使用Timer进行任务调度了。
【3】ScheduledThreadPoolExecutor 工作原理
【4】源码
【5】实现例子
BusinessPool.java:
package test2;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class BusinessPool {
private ScheduledThreadPoolExecutor executor;
BusinessPool() {
}
public static class BusinessPoolThreadFactory implements ThreadFactory {
final ThreadGroup group = Thread.currentThread().getThreadGroup();
final AtomicInteger threadNumber = new AtomicInteger(1);
final String namePrefix = "business-pool";
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
public void init() {
this.executor = new ScheduledThreadPoolExecutor(1, new BusinessPoolThreadFactory());
}
public void schedule(Runnable runnable, long delay, TimeUnit unit) {
executor.schedule(runnable, delay, unit);
}
public void execute(Runnable runnable) {
executor.execute(runnable);
}
}
test.java:
package test2;
import java.util.concurrent.TimeUnit;
public class test23 {
public static void main(String[] args) {
BusinessPool businessPool = new BusinessPool();
businessPool.init();
businessPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println("Hello world 0_0|||");
}
}, 3, TimeUnit.SECONDS);
}
}
输出结果(延时3s执行线程):
Hello world 0_0|||
参考博文:https://www.jianshu.com/p/925dba9f5969