原文转载
https://mp.weixin.qq.com/s/9GRxBCpeDss-llecrwo-lw
- 使用线程创建
- 使用TimerTask创建
- 使用线程池创建
- 使用Quartz创建
- 使用springboot的@Scheduled注解
public class CreatByThread {
private static int count = 0;
private static void timerTask(){
Runnable runnable = new Runnable() {
@SneakyThrows
@Override
public void run() {
while (true){
Thread.sleep(1000);
count++;
System.err.println(count);
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
public static void main(String[] args) {
timerTask();//原生写法
new Thread(()->{//lambda表达式
while (true){
try {
Thread.sleep(1000);
count++;
System.out.println(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
原文转载
https://blog.csdn.net/xieyuooo/article/details/8607220/
首先要明白:Timer是一个调度器,TimerTask只是一个实现了run方法的一个类(需要自己来实现)
Timer和TimerTask的组合是一个单线程,如果创建多线程会使用:Executor.newScheduledThreadPool
常见的Timer类中的方法:
#调度一个task,经过dealy(ms)后开始调度,仅仅调度一次 public void schedule(TimerTask task,long delay)
#调度一个task,在指定的时间点time上调度一次 public void schedule(timertask task,Date t)
#调度一个task,在dealy(ms)后开始调度,每次调度完后,最少等待period(ms)后才开始调度 public void schedule(TimerTask task,long delay,long period)
#和上一个方法类似,唯一区别就是传入的第二个参数为第一次调度的时间 public void schedule(TimerTask task,Date firstTime,long period)
#调度一个task,在delay(ms)后开始调度,然后经过period(ms)再次调度,似乎和第三个方法类似,但不然,区别: #1、schedule在计算下一次执行时间的时候,是通过当前时间(在任务执行前得到)+时间片; #2、scheduleAtFixedRate方法是通过当前需要执行的时间(也就是现在需要执行的时间)+时间片; #3、schedule是运行时的实际时间,而scheduleAtFixedRate是理论时间。例如:schedule的时间片是5s,那么理论会在5、10、15、20这些时间片被调度,但如果由于某些cpu征用导致未调度,假如等到8s才被调度一次,那么schedule方法计算出来的下一次调度时间应该是13s,而不是10s,这样有可能下次越到20s后而被少调度一次或多次;而scheduleAtFixedRate就是每次理论计算出下一次需要调度的时间用以排序,若第8s被调度了,那么计算出应该是第10s,所以它距离当前时间是2s,那么在调度队列排序中,会优先调度; #4、scheduleAtFixedRate可以减少漏调度的情况; public void scheduleAtFixedRate(TimerTask timer,long delay,long period)
#方法和上一个方法类似,唯一的区别是第一次调度的时间设置为Date,而不是当前时间的一个时间片 public void scheduleAtFixedRate(TimerTask timer,Date firstTime,long period)
public class CreatByTimerTask {
private static int count = 0;
private static void timerTask(){
TimerTask timerTask = new TimerTask() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(1000);
count++;
System.err.println(count);
}
};
Timer timer = new Timer();
timer.schedule(timerTask,0,1000);//每秒调度一次
}
public static void main(String[] args) {
timerTask();//原生写法
new Timer().schedule(new TimerTask() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(1000);
count++;
System.out.println(count);
}
},0,1000);
}
}
public class CreatByThreadPool {
private static int count = 0;
private static void timerTask(){
Runnable runnable = new Runnable() {
@Override
public void run() {
count++;
System.err.println(count);
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
//第二个参数为首次执行的延迟时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable,1,1, TimeUnit.SECONDS);
}
public static void main(String[] args) {
timerTask();
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(()->{
count++;
System.out.println(count);
},1,1,TimeUnit.SECONDS);
}
}
maven依赖
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartzartifactId>
<version>2.2.1version>
dependency>
<dependency>
<groupId>org.quartz-schedulergroupId>
<artifactId>quartz-jobsartifactId>
<version>2.2.1version>
dependency>
实现了Quratz框架接口的类
@Service
public class QuartzServiceImpl implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.err.println("this is a quartz method , now time:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
启动类
public class creatByQuartz {
private static void timerTask() throws SchedulerException {
//1、创建scheduler的工厂
StdSchedulerFactory factory = new StdSchedulerFactory();
//2、从工厂中获取调度器实列
Scheduler scheduler = factory.getScheduler();
//3、创建JobDetail
JobDetail job = JobBuilder.newJob(QuartzServiceImpl.class)
//job描述
.withDescription("this is a quartz job")
//job的name和group
.withIdentity("quartzJob", "quartzGroup")
.build();
//任务运行的时间,simpleSchedule类型触发器有效,3秒后启动任务
long time = System.currentTimeMillis()+3*1000L;
Date statTime = new Date(time);
//4、创建Trigger(使用SimpleScheduleBuilder或者CronScheduleBuilder)
CronTrigger trigger = TriggerBuilder.newTrigger()
.withDescription("this is trigger")
.withIdentity("quartzTrigger", "quartzTriggerGroup")
// .withSchedule(SimpleScheduleBuilder.simpleSchedule())
.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?"))//两秒执行一次,采用cron表达式
.startAt(statTime)//默认当前时间启动
.build();
//5、注册任务和定时器
scheduler.scheduleJob(job,trigger);
//6、启动调度器
scheduler.start();
}
public static void main(String[] args) throws SchedulerException {
timerTask();
}
}
https://blog.csdn.net/yjltx1234csdn/article/details/105846493
https://www.cnblogs.com/sunset-red/p/13794009.html
在启动类上添加注解:@EnableScheduling
@Slf4j
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)//排除连接数据库
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableScheduling //开启定时任务
public class IdempotencyApplication {
public static void main(String[] args) throws UnknownHostException {
ConfigurableApplicationContext applicationContext = SpringApplication.run(IdempotencyApplication.class, args);
ConfigurableEnvironment env = applicationContext.getEnvironment();
String ip = Inet6Address.getLocalHost().getHostAddress();
String port = env.getProperty("server.port");
String path = env.getProperty("server.servlet.context-path");
log.info("----------------------------------\r\n{}","http://".concat(ip).concat(":").concat(port+path));
}
}
用注解:@Scheduled标识定时任务方法
@Configuration
@Component
public class CreatByScheduled {
// @Scheduled(cron = "0/5 * * * * ?")//采用cron表达式执行一次定时任务
@Scheduled(fixedRate = 5000)//指定时间5s执行一次定时任务
public static void timerTask(){
System.err.println("this is a timerTask:"+ LocalDate.now());
}
}
项目启动后,定时任务执行
cron表达式说明
https://blog.csdn.net/hu_dongyang/article/details/114270232
springboot使用@Scheduled
https://www.jianshu.com/p/c7492aeb35a1