亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java學(xué)習(xí)教程之定時(shí)任務(wù)全家桶

 更新時(shí)間:2020年11月22日 17:29:34   作者:挑戰(zhàn)者V  
這篇文章主要給大家介紹了關(guān)于Java學(xué)習(xí)教程之定時(shí)任務(wù)全家桶的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

定時(shí)任務(wù)應(yīng)用非常廣泛,Java提供的現(xiàn)有解決方案有很多。

本次主要講schedule、quartz、xxl-job、shedlock等相關(guān)的代碼實(shí)踐。

一、SpringBoot使用Schedule

核心代碼:

@Component
public class ScheduleTask {

 private Logger logger = LoggerFactory.getLogger(ScheduleTask.class);

 @Scheduled(cron = "0/1 * * * * ? ")
 public void one() {

 logger.info("one:" + new Date());
 }

 @Scheduled(cron = "0/1 * * * * ? ")
 public void two() {

 logger.info("two:" + new Date());
 }


 @Scheduled(cron = "0/1 * * * * ? ")
 public void three() {

 logger.info("three:" + new Date());
 }
}

運(yùn)行效果如下:

除此之外還可以這樣實(shí)現(xiàn),核心代碼:

@PropertySource(value = {
 "classpath:task.properties",
}, encoding = "utf-8")
@Component("scheduleTask")
public class ScheduleTask implements SchedulingConfigurer {


 @Value("${TEST_JOB_TASK_CRON}")
 private String cron;

 @Override
 public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {

 scheduledTaskRegistrar.addTriggerTask(new Runnable() {

  @Override
  public void run() {
  System.out.println("執(zhí)行任務(wù):" + DateUtil.date());


  }

 }, new Trigger() {
  @Override
  public Date nextExecutionTime(TriggerContext triggerContext) {
  return new CronTrigger(cron).nextExecutionTime(triggerContext);
  }
 });
 }

 public void setCron(String cron) {
 this.cron = cron;
 }
}

有朋友或許很疑惑,為什么要寫(xiě)這么一大堆,這個(gè)與前面的代碼又有何區(qū)別呢?

區(qū)別是多線程并行。其實(shí)多線程并行也可以不用這么寫(xiě),只需寫(xiě)一段核心配置類(lèi)代碼即可。

定時(shí)任務(wù)多線程配置類(lèi):

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

 public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
 scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
 }
}

再次啟動(dòng),查看效果,如下:

由此看出走不同的線程執(zhí)行,不同的線程執(zhí)行的好處是,如果某一個(gè)線程掛掉后,并不會(huì)阻塞導(dǎo)致其它定時(shí)任務(wù)無(wú)法執(zhí)行。

另外如果要想并發(fā)執(zhí)行,前面的配置可以不要,直接用SpringBoot提供的現(xiàn)成注解即可,核心代碼如下:

@Component
@EnableAsync
public class ScheduleAsyncTask {

 private Logger logger = LoggerFactory.getLogger(ScheduleAsyncTask.class);

 @Scheduled(cron = "0/1 * * * * ? ")
 @Async
 public void one() {

 logger.info("one Async:" + new Date());
 }

 @Scheduled(cron = "0/1 * * * * ? ")
 @Async
 public void two() {

 logger.info("two Async:" + new Date());
 }


 @Scheduled(cron = "0/1 * * * * ? ")
 @Async
 public void three() {

 logger.info("three Async:" + new Date());
 }
}

除此外,還有基于schedule動(dòng)態(tài)定時(shí)任務(wù)(所謂動(dòng)態(tài)只不過(guò)是指cron表達(dá)式放在對(duì)應(yīng)的數(shù)據(jù)表里),簡(jiǎn)單示例代碼:

@Configuration
public class DynamicScheduleTask implements SchedulingConfigurer {

 @Autowired
 @SuppressWarnings("all")
 CronMapper cronMapper;

 @Mapper
 public interface CronMapper {
 @Select("select cron from cron limit 1")
 public String getCron();
 }

 /**
 * 執(zhí)行定時(shí)任務(wù).
 */
 public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

 taskRegistrar.addTriggerTask(
  //1.添加任務(wù)內(nèi)容(Runnable)
  () -> System.out.println("執(zhí)行動(dòng)態(tài)定時(shí)任務(wù): " + LocalDateTime.now().toLocalTime()),
  //2.設(shè)置執(zhí)行周期(Trigger)
  triggerContext -> {
   //2.1 從數(shù)據(jù)庫(kù)獲取執(zhí)行周期
   String cron = cronMapper.getCron();
   //2.2 合法性校驗(yàn).
   if (StringUtils.isEmpty(cron)) {
   // Omitted Code ..
   }
   //2.3 返回執(zhí)行周期(Date)
   return new CronTrigger(cron).nextExecutionTime(triggerContext);
  }
 );
 }



}

核心配置文件(application.yml):

spring:
 datasource:
 url: jdbc:mysql://127.0.0.1:3306/test
 username: root
 password: 1234

SQL腳本:

DROP DATABASE IF EXISTS `test`;
CREATE DATABASE `test`;
USE `test`;
DROP TABLE IF EXISTS `cron`;
CREATE TABLE `cron` (
 `cron_id` varchar(30) NOT NULL PRIMARY KEY,
 `cron` varchar(30) NOT NULL 
);
INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');

運(yùn)行效果如下:

二、SpringBoot使用Quartz

1.Maven依賴

<!--引入quartz定時(shí)框架-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

2.配置文件

spring:
 quartz:
 #相關(guān)屬性配置
 properties:
  org:
  quartz:
   scheduler:
   instanceName: clusteredScheduler
   instanceId: AUTO
   jobStore:
   class: org.quartz.impl.jdbcjobstore.JobStoreTX
   driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
   tablePrefix: QRTZ_
   isClustered: true
   clusterCheckinInterval: 10000
   useProperties: false
   threadPool:
   class: org.quartz.simpl.SimpleThreadPool
   threadCount: 10
   threadPriority: 5
   threadsInheritContextClassLoaderOfInitializingThread: true
 #數(shù)據(jù)庫(kù)方式
 job-store-type: jdbc
 #初始化表結(jié)構(gòu)
 jdbc:
  initialize-schema: always
 datasource:
 url: jdbc:mysql://127.0.0.1:3306/test
 username: root
 password: 1234

3.啟動(dòng)類(lèi)

@SpringBootApplication
@EnableScheduling
public class BlogQuartzApplication {

 public static void main(String[] args) {
  SpringApplication.run(BlogQuartzApplication.class, args);
 }


}

4.配置類(lèi)

@Configuration
public class QuartzConfiguration {
 // 使用jobDetail包裝job
 @Bean
 public JobDetail myCronJobDetail() {
  return JobBuilder.newJob(CouponTimeOutJob.class).withIdentity("couponTimeOutJob").storeDurably().build();
 }

 // 把jobDetail注冊(cè)到Cron表達(dá)式的trigger上去
 @Bean
 public Trigger CronJobTrigger() {
  CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");

  return TriggerBuilder.newTrigger()
    .forJob(myCronJobDetail())
    .withIdentity("CouponTimeOutJobTrigger")
    .withSchedule(cronScheduleBuilder)
    .build();
 }
}

5.定時(shí)任務(wù)類(lèi)

public class CouponTimeOutJob extends QuartzJobBean {
 @Override
 protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
  System.out.println("定時(shí)任務(wù)執(zhí)行");
 }
}

6.啟動(dòng)成功不報(bào)錯(cuò)

(1)對(duì)應(yīng)的數(shù)據(jù)庫(kù)會(huì)生成定時(shí)任務(wù)相關(guān)的數(shù)據(jù)表

(2)控制臺(tái)不斷輸出定時(shí)任務(wù)執(zhí)行日志

三、SpringBoot使用xxl-job

之前寫(xiě)過(guò)一樣的例子,如今簡(jiǎn)化了下。

關(guān)于xxl-job使用詳情,可以參考我的這篇文章:

SpringBoot整合Xxl-Job

1.Maven依賴

<dependency>
 <groupId>com.xuxueli</groupId>
 <artifactId>xxl-job-core</artifactId>
 <version>2.2.0</version>
</dependency>

2.配置類(lèi)

@Configuration
public class XxlJobConfig {
 private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

 @Value("${xxl.job.admin.addresses}")
 private String adminAddresses;

 @Value("${xxl.job.executor.appname}")
 private String appName;

 @Value("${xxl.job.executor.ip}")
 private String ip;

 @Value("${xxl.job.executor.port}")
 private int port;

 @Value("${xxl.job.accessToken}")
 private String accessToken;

 @Value("${xxl.job.executor.logpath}")
 private String logPath;

 @Value("${xxl.job.executor.logretentiondays}")
 private int logRetentionDays;


 @Bean(initMethod = "start", destroyMethod = "destroy")
 public XxlJobSpringExecutor xxlJobExecutor() {
  logger.info(">>>>>>>>>>> xxl-job config init.");
  XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
  xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
  xxlJobSpringExecutor.setAppname(appName);
  xxlJobSpringExecutor.setIp(ip);
  xxlJobSpringExecutor.setPort(port);
  xxlJobSpringExecutor.setAccessToken(accessToken);
  xxlJobSpringExecutor.setLogPath(logPath);
  xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

  return xxlJobSpringExecutor;
 }

}

3.配置文件內(nèi)容

# web port
server.port=8081
# no web
#spring.main.web-environment=false
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### xxl-job, access token
xxl.job.accessToken=
### xxl-job executor appname
xxl.job.executor.appname=blog-job-xxl-job
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address=
### xxl-job executor server-info
xxl.job.executor.ip=
xxl.job.executor.port=8888
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30

4.定時(shí)任務(wù)類(lèi)

@Component
public class XxlJobTaskExample {


 @XxlJob("blogJobHandler")
 public ReturnT<String> blogJobHandler(String param) throws Exception {
  System.out.println("執(zhí)行");
  XxlJobLogger.log("XXL-JOB, Hello World.");

  for (int i = 0; i < 5; i++) {
   XxlJobLogger.log("beat at:" + i);
   TimeUnit.SECONDS.sleep(2);
  }
  return ReturnT.SUCCESS;
 }

}

5.執(zhí)行效果

分別如下所示:

四、SpringBoot使用ShedLock

1.導(dǎo)入Maven依賴

<!-- 分布式定時(shí)任務(wù)鎖 -->
 <!-- https://mvnrepository.com/artifact/net.javacrumbs.shedlock/shedlock-spring -->
 <dependency>
  <groupId>net.javacrumbs.shedlock</groupId>
  <artifactId>shedlock-spring</artifactId>
  <version>4.0.4</version>
 </dependency>
 <!-- 使用redis做分布式任務(wù) -->
 <dependency>
  <groupId>net.javacrumbs.shedlock</groupId>
  <artifactId>shedlock-provider-redis-spring</artifactId>
  <version>2.5.0</version>
 </dependency>
 <!-- redis組件 -->
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>

2.編寫(xiě)配置類(lèi)

@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "PT30M")
public class ShedLockConfig {

 @Bean
 public LockProvider lockProvider(RedisTemplate redisTemplate) {
  return new RedisLockProvider(redisTemplate.getConnectionFactory());

 }

}

3.編寫(xiě)具體的定時(shí)任務(wù)

@Component
public class TaskSchedule {

 /**
  * 每分鐘執(zhí)行一次
  * [秒] [分] [小時(shí)] [日] [月] [周] [年]
  */
 @Scheduled(cron = "1 * * * * ?")
 @SchedulerLock(name = "synchronousSchedule")
 public void SynchronousSchedule() {
  
  System.out.println("Start run schedule to synchronous data:" + new Date());

 }
}

4.編寫(xiě)啟動(dòng)類(lèi)

@SpringBootApplication
@EnableScheduling
public class ShedLockRedisApplication {
 public static void main(String[] args) {
  SpringApplication.run(ShedLockRedisApplication.class);
 }
}

5.配置文件

server:
 tomcat:
 uri-encoding: UTF-8
 max-threads: 1000
 min-spare-threads: 30
 port: 8083

spring:
 redis:
 database: 0
 host: localhost
 port: 6379
 password:  # 密碼(默認(rèn)為空)
 timeout: 6000ms # 連接超時(shí)時(shí)長(zhǎng)(毫秒)
 jedis:
  pool:
  max-active: 1000 # 連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)
  max-wait: -1ms  # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)
  max-idle: 10  # 連接池中的最大空閑連接
  min-idle: 5  # 連接池中的最小空閑連接

6.測(cè)試

我之所以用shedlock是因?yàn)榇_保在集群環(huán)境下各微服務(wù)的定時(shí)任務(wù)只執(zhí)行一個(gè),而不是全部都運(yùn)行相同的定時(shí)任務(wù)。

本次測(cè)試效果如下:

本次代碼例子已放至我的GitHub:https://github.com/developers-youcong/blog-job

到此這篇關(guān)于Java學(xué)習(xí)教程之定時(shí)任務(wù)全家桶的文章就介紹到這了,更多相關(guān)Java定時(shí)任務(wù)全家桶內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA中Integer值的范圍實(shí)例代碼

    JAVA中Integer值的范圍實(shí)例代碼

    這篇文章主要介紹了JAVA中Integer值的范圍實(shí)例代碼,需要的朋友可以參考下
    2017-09-09
  • Java延遲隊(duì)列原理與用法實(shí)例詳解

    Java延遲隊(duì)列原理與用法實(shí)例詳解

    這篇文章主要介紹了Java延遲隊(duì)列原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了延遲隊(duì)列的概念、原理、功能及具體使用方法,需要的朋友可以參考下
    2018-09-09
  • mybatis中<choose>標(biāo)簽的用法說(shuō)明

    mybatis中<choose>標(biāo)簽的用法說(shuō)明

    這篇文章主要介紹了mybatis中<choose>標(biāo)簽的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java網(wǎng)絡(luò)編程TCP實(shí)現(xiàn)聊天功能

    Java網(wǎng)絡(luò)編程TCP實(shí)現(xiàn)聊天功能

    這篇文章主要為大家詳細(xì)介紹了Java網(wǎng)絡(luò)編程TCP實(shí)現(xiàn)聊天功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java Listener監(jiān)聽(tīng)器使用規(guī)范詳細(xì)介紹

    Java Listener監(jiān)聽(tīng)器使用規(guī)范詳細(xì)介紹

    監(jiān)聽(tīng)器是一個(gè)專(zhuān)門(mén)用于對(duì)其他對(duì)象身上發(fā)生的事件或狀態(tài)改變進(jìn)行監(jiān)聽(tīng)和相應(yīng)處理的對(duì)象,當(dāng)被監(jiān)視的對(duì)象發(fā)生情況時(shí),立即采取相應(yīng)的行動(dòng)。監(jiān)聽(tīng)器其實(shí)就是一個(gè)實(shí)現(xiàn)特定接口的普通java程序,這個(gè)程序?qū)iT(mén)用于監(jiān)聽(tīng)另一個(gè)java對(duì)象的方法調(diào)用或?qū)傩愿淖?/div> 2023-01-01
  • 深入理解Java設(shè)計(jì)模式之外觀模式

    深入理解Java設(shè)計(jì)模式之外觀模式

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之外觀模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2021-11-11
  • Java 反射之私有字段和方法詳細(xì)介紹

    Java 反射之私有字段和方法詳細(xì)介紹

    本文將介紹Java 反射之私有字段和方法的應(yīng)用,需呀了解的朋友可以參考下
    2012-11-11
  • java?Object類(lèi)中常用API分享

    java?Object類(lèi)中常用API分享

    Object類(lèi)是java中所有類(lèi)的祖宗類(lèi),因此java中所有的類(lèi)的對(duì)象都可以直接使用Object類(lèi)中提供的一些方法,下面小編為大家整理了Object類(lèi)中常用API,希望對(duì)大家有所幫助
    2023-10-10
  • spring boot啟動(dòng)加載數(shù)據(jù)原理分析

    spring boot啟動(dòng)加載數(shù)據(jù)原理分析

    實(shí)際應(yīng)用中,我們會(huì)有在項(xiàng)目服務(wù)啟動(dòng)的時(shí)候就去加載一些數(shù)據(jù)或做一些事情這樣的需求。這時(shí)spring Boot 為我們提供了一個(gè)方法,通過(guò)實(shí)現(xiàn)接口 CommandLineRunner 來(lái)實(shí)現(xiàn)。下面給大家詳細(xì)介紹下,需要的的朋友參考下吧
    2017-04-04
  • IDEA正則表達(dá)式全局搜索圖文教程

    IDEA正則表達(dá)式全局搜索圖文教程

    當(dāng)您要搜索和替換特定的文本模式時(shí),請(qǐng)使用正則表達(dá)式,下面這篇文章主要給大家介紹了關(guān)于IDEA正則表達(dá)式全局搜索的相關(guān)資料,文中通過(guò)代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08

最新評(píng)論