定时器是一种控制任务延时调用,或者周期调用的技术
作用:闹钟,定时邮件发送
定时器的实现方式:
方式1:Timer(定时器)
构造器
public Timer() 创建Timer定时器对象
方法
public void schedule(TimerTask task,long delay,long period) 开启一个定时器,按照计划处理TimerTask任务
public class Test {
public static void main(String[] args) {
// 创建定时器对戏
Timer t=new Timer();
t.schedule(new TimerTask() {//第一个参数为任务对象 ,这里用的是匿名内部类的形式
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行了");
}
}, 2000,3000); //第二个参数是延时时间,第三个参数为周期时间
}
}
Timer定时器的特点和存在的问题
1:Timer是单线程,处理多个任务按照顺序执行,存在延时与设置定时器的时间有出入
package DomeTimer;
import java.util.Timer;
import java.util.TimerTask;
public class Test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Timer t=new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"被执行A");
try {
Thread.sleep(20000);//上面的线程休眠了,下面的要等,下面的定时器对象设置的时间就不准了
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 2000, 3000);
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"被执行B");
}
}, 2000,3000);
}
}
2:可能因为其中某个任务异常使Timer线程死掉,从而影响后去任务执行
package DomeTimer;
import java.util.Timer;
import java.util.TimerTask;
public class Test3 {
public static void main(String[] args) {
Timer t=new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"我会出现异常");
System.out.println(10/0);//引发异常
}
},1000, 1000);
t.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"上面出现异常我根本执行不了");
}
},1000, 1000);
}
}
方式2:ScheduledExecutorService定时器
ScheduleExecutorService是Jdk1.5中引入了并发包,目的是为了弥补Timer的缺陷,ScheduleExecutorService内部为线程池
方法:
public satic ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 得到线程池对象
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimerUnit unit) 周期调度方法
优点
基于线程池,某个任务的执行情况不会影响其它定时任务的执行
package DomeTimer;
import java.util.Date;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建线程池
ScheduledThreadPoolExecutor pool=new ScheduledThreadPoolExecutor(3);
//ScheduledThreadPoolExecutor pool1=(ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(3);
//开始定时任务
pool.scheduleWithFixedDelay(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"AAA"+new Date());
}
}, 0, 2, TimeUnit.SECONDS);
}
}