Redisson distributed lock integrated with @Scheduled doesn’t guarantee a single scheduled job execution at the same time
Here is a example below:
Thread.sleep(10000); // 如果不加改行代码,则该方法执行时间很短,比如 1ms ,那么 其他线程也是有机会重复执行的
。
因此,要想保证只有1个scheduled task 被执行,必须保证 在 其他线程获取锁失败,比如超时失败,或者其他的条件失败。
故:可以强制在 方法末尾 必须加上 Thread.sleep(10000);
, 保证锁超时。
小伙伴们还有其他方法吗?
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = CameraApplication.class)
@Slf4j
public class RedissonTests {
@Resource
RedissonClient redissonClient;
@Resource
ExecutorService executorService;
@Test
public void testLock() {
try {
//Simulating cluster timer tasks with multiple threads
for (int i = 1; i <= 5; i++) {
int id = i;
executorService.execute(new Runnable() {
@Override
public void run() {
RLock rLock = redissonClient.getLock("testLock");
try {
log.info(id + " Request Lock");
//Attempt to lock, wait up to 5 seconds, unlock automatically 10 seconds after lock
boolean lockRes = rLock.tryLock(5, 10, TimeUnit.SECONDS);
if (lockRes) {
try {
log.info(id + " Application Successful,Processing business logic");
Thread.sleep(10000); // 必须强制等待保证锁超时 ,那么 其他线程也就没机会重复执行了
} finally {
//Is it locked and whether the current thread has acquired a lock
if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
rLock.unlock();
log.info(id + " Release lock");
}
}
} else {
log.info(id + " Failed to apply for lock=" + lockRes);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
Thread.sleep(500000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}