本文以MYSQL为例,存储lock数据。更多参考ShedLock github.
Mysql 建表
CREATE TABLE shedlock(
name VARCHAR(64) NOT NULL,
lock_until TIMESTAMP(3) NOT NULL,
locked_at TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name));
添加依赖
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.20.1</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>4.20.1</version>
</dependency>
配置LockProvider
@Configuration
@EnableScheduling
public class ScheduledTaskConfig {
@Autowired
private DataSource dataSource;
@Bean
public LockProvider lockProvider() {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withJdbcTemplate(new JdbcTemplate(dataSource))
.withTimeZone(TimeZone.getTimeZone("UTC"))
.build()
);
}
}
编写调度任务
@Service
@EnableSchedulerLock(defaultLockAtMostFor = "4m")
public class ScheduledTask {
@Scheduled(cron = "0 0 1 * * ?")
@SchedulerLock(name = "task1", lockAtMostFor = "60m", lockAtLeastFor = "40m")
public void task1() {
//task1
}
}
测试
public class ScheduledTestTask {
@Scheduled(cron = "0/3 * * * * *")
@SchedulerLock(name = "t1", lockAtMostFor = "1m", lockAtLeastFor = "2s")
public void t1() {
System.out.println("Task 1 begin: " + LocalDateTime.now().toString());
}
@Scheduled(cron = "0/3 * * * * *")
@SchedulerLock(name = "t1", lockAtMostFor = "1m", lockAtLeastFor = "2s")
public void t2() {
System.out.println("Task 2 begin: " + LocalDateTime.now().toString());
}
@Scheduled(cron = "0/3 * * * * *")
@SchedulerLock(name = "t3", lockAtMostFor = "1m", lockAtLeastFor = "2s")
public void t3() {
System.out.println("Task 3 begin: " + LocalDateTime.now().toString());
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
@Configuration
public class ScheduleTaskTest {
@Bean
public ScheduledTestTask ScheduledTestTask() {
return new ScheduledTestTask();
}
@Test
public void test() {
try {
Thread.sleep(100_000l);
} catch (Exception e) {
System.out.println(e);
}
}
}
测试结果如下:
每三秒,任务t1 和 t3都会被执行,但是 t1 有两个方法,交替执行。符合预期。
Task 1 begin: 2021-03-03T17:18:54.250
Task 3 begin: 2021-03-03T17:18:54.376
Task 3 begin: 2021-03-03T17:18:57.029
Task 2 begin: 2021-03-03T17:18:57.065
Task 1 begin: 2021-03-03T17:19:00.019
Task 3 begin: 2021-03-03T17:19:00.052
Task 2 begin: 2021-03-03T17:19:03.018
Task 3 begin: 2021-03-03T17:19:03.050
Task 2 begin: 2021-03-03T17:19:06.017
Task 3 begin: 2021-03-03T17:19:06.040
Task 2 begin: 2021-03-03T17:19:09.017
Task 3 begin: 2021-03-03T17:19:09.040
Task 2 begin: 2021-03-03T17:19:12.018
Task 3 begin: 2021-03-03T17:19:12.048
Task 1 begin: 2021-03-03T17:19:15.016
Task 3 begin: 2021-03-03T17:19:15.047