方式一:Timer
TimerTask类实际上是实现了Runnable。
Timer定时器的特点和存在的问题:
1、Timer是单线程,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入。
2、由于单线程特性,一旦其中的某个任务抛出异常使Timer线程死掉,其他任务都不能继续执行。
public Timer() 创建Timer定时器对象
public void schedule(TimerTask task, long delay, long period) 开启一个定时器,按照计划处理TimerTask任务
// 1、创建Timer定时器
Timer timer = new Timer(); // 定时器本身就是一个单线程。
// 2、调用方法,处理定时任务
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行AAA~~~" + new Date());
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}, 0, 2000);//0s后开始,每2s执行一次。timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行BB~~~"+ new Date());
System.out.println(10/0);//抛异常了这个线程就不再执行了。
}
}, 0, 2000);//这个线程会在上一个线程执行了第一次之后才执行,也就是睡了5s后才执行第一次。timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行CCC~~~"+ new Date());
}
}, 0, 3000);
方式二: ScheduledExecutorService
内部是线程池,弥补了Timer的缺陷。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 得到线程池对象
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 周期调度方法
// 1、创建ScheduledExecutorService线程池,做定时器
ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);// 2、开启定时任务
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行输出:AAA ==》 " + new Date());
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, 0, 2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行输出:BBB ==》 " + new Date());
System.out.println(10 / 0);
}
}, 0, 2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行输出:CCC ==》 " + new Date());
}
}, 0, 2, TimeUnit.SECONDS);