普通thread--
这是最常见的, 创建一个thread,然后让它在while循环里一直运行着,
通过sleep方法来达到定时任务的效果。这样可以快速简单的实现,
package com.iotek.classtype;
public class Task1 {
public static void main(String[] args) {
final long timeInterval=1000;
Runnable runnable =new Runnable() {
@Override
public void run() {
while(true) {
System.out.println("hello !!!");
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
Thread thread=new Thread(runnable);
thread.start();
}
}
Timer类
Timer类可以调度任务,TimerTask则是通过在run()方法里实现具体任务。 Timer实例可以调度多任务,它是线程安全的。
当Timer的构造器被调用时,它创建了一个线程,这个线程可以用来调度任务。 下面是代码:
通过
timer.schedule()方法
package com.iotek.classtype;
import java.util.Timer;
import java.util.TimerTask;
public class Task2 {
public static void main(String[] args) {
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
System.out.println("HELLO");
}
};
Timer timer=new Timer();
long delay=0;
long intevalPeriod=1*1000;
timer.schedule(timerTask, delay, intevalPeriod);
}
}
ScheduledExecutorService
ScheduledExecutorService是从Java SE5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式。
相比于上两个方法,它有以下好处:
相比于Timer的单线程,它是通过线程池的方式来执行任务的
可以很灵活的去设定第一次执行任务delay时间
提供了良好的约定,以便设定执行的时间间隔
package com.iotek.classtype;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Task3 {
public static void main(String[] args) {
Runnable runnable=new Runnable() {
@Override
public void run() {
System.out.println("hello");
}
};
ScheduledExecutorService service=Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 10,1,TimeUnit.SECONDS);
}
}
JAVA实现定时任务的几种方式
JDK 自带的定时器实现
Timer类
这个类允许你调度一个java.util.TimerTask任务。主要有以下几个方法:
//schedule(TimerTask task, long delay) 延迟 delay 毫秒 执行
public static void main(String[] args) {
for(int i=0;i<10;i++) {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" run");
}
}, 1000);
}
View Code
//schedule(TimerTask task, Date time) 特定时间执行
public static void main(String[] args) {
for (int i = 0; i <20; i++) {
new Timer("TIMER"+i).schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" RUN");
}
}, new Date(System.currentTimeMillis()+2000));
}
}
View Code
//schedule(TimerTask task, long delay, long period) 延迟 delay 执行并每隔period 执行一次
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Timer(" timer"+i).scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"run");
}
}, 1000, 2000);
}
}
View Code
ScheduledExecutorService 接口实现类
ScheduledExecutorService 是JAVA 1.5 后新增的定时任务接口,主要有以下几个方法。
ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);
ScheduledFuture<V> schedule(Callable<V> callable,long delay, TimeUnit unit);
ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnitunit);
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnitunit);
默认实现为ScheduledThreadPoolExecutor 继承了ThreadPoolExecutor 的线程池特性,配合future特性,比Timer更强大。 具体用法可以阅读JDK文档;spring Task内部也是依靠它实现的
。示例代码:
public static void main(String[] args) {
ScheduledExecutorService service=Executors.newSingleThreadScheduledExecutor();
for (int i = 0; i < 10; i++) {
service.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " run ");
}
}, 2, TimeUnit.SECONDS);
}
service.shutdown();
}
View Code
Quartz 定时器实现
Quartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔来调度作业。它实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。可以动态的添加删除定时任务,另外很好的支撑集群调度。简单地创建一个org.quarz.Job接口的Java类,Job接口包含唯一的方法:
public void execute(JobExecutionContext context) throws JobExecutionException;
在Job接口实现类里面,添加需要的逻辑到execute()方法中。配置好Job实现类并设定好调度时间表(Trigger),Quartz就会自动在设定的时间调度作业执行execute()。
整合了Quartz的应用程序可以重用不同事件的作业,还可以为一个事件组合多个作业。Quartz通过属性文件来配置JDBC事务的数据源、全局作业、触发器侦听器、插件、线程池等等。(quartz.properties)
通过maven引入依赖(这里主要介绍2.3.0) 注意:shiro-scheduler中依赖的是1.x版本 如果同时使用会冲突
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
创建Job类
public class TestJob implements Job{
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
println(Thread.currentThread().getName() + " test job begin " + DateUtil.getCurrentTimeStr());
}
}
调度任务
public static void main(String[] args) throws InterruptedException, SchedulerException {
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
// 开始
scheduler.start();
// job 唯一标识 test.test-1
JobKey jobKey = new JobKey("test" , "test-1");
JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("test" , "test")
// 延迟一秒执行
.startAt(new Date(System.currentTimeMillis() + 1000))
// 每隔一秒执行 并一直重复
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
.build();
scheduler.scheduleJob(jobDetail , trigger);
Thread.sleep(5000);
// 删除job
scheduler.deleteJob(jobKey);
}
关于简单使用,可以参考quartz的example,下面链接是一些入门帮助。
Quartz定时任务学习(一)简单任务
Quartz定时任务学习(二)web应用
Quartz定时任务学习(三)属性文件和jar
深入学习可以阅读官方文档和相关博客阅读
以下为推荐博客地址
quartz详解2:quartz由浅入深
Spring 相关的任务调度
Spring 3.0+ 自带的任务调度实现,主要依靠TaskScheduler
接口的几个实现类实现。删除和修改任务比较麻烦。
主要用法有以下三种:
- Spring配置文件实现
- 注解实现
- 代码动态添加
配置文件实现
spring-schedule.xml
<task:scheduler id="myScheduler" pool-size="10" />
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="job" method="test" cron="0 * * * * ?"/>
</task:scheduled-tasks>
注解实现
spring-schedule.xml
<task:scheduler id="myScheduler" pool-size="10" />
// 启用注解
<task:annotation-driven scheduler="myScheduler"/>
@Component
public class Task{
@Scheduled(cron="0/5 * * * * ? ") //每5秒执行一次
public void execute(){
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(DateTime.now().toDate())+"*********B任务每5秒执行一次进入测试");
}
}
代码动态添加
spring-schedule.xml
<bean id = "myScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="10"/>
<property name="threadGroupName" value="myScheduler" />
<property name="threadNamePrefix" value="-1" />
</bean>
<task:annotation-driven scheduler="myScheduler"/>
@Component
public class Test {
@Autowired
private ThreadPoolTaskScheduler myScheduler;
public void addJob(){
myScheduler.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " run ");
}
} , new CronTrigger("0/5 * * * * ? ")); //每5秒执行一次
}
}
spring 结合 quartz 实现任务调度
动态增加删除
@Component
public class Test {
@Autowired
private SchedulerFactoryBean quartzScheduler;
public void addJob() throws SchedulerException {
Scheduler scheduler = quartzScheduler.getScheduler();
JobKey jobKey = new JobKey("test", "test");
if (scheduler.checkExists(jobKey)) {
return;
}
JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test", "test")
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever()).build();
scheduler.scheduleJob(jobDetail, trigger);
}
}