Java调度任务如何使用分布式锁保证相同任务在一个周期里只执行一次?

简介: 【10月更文挑战第29天】Java调度任务如何使用分布式锁保证相同任务在一个周期里只执行一次?

在Java中,使用分布式锁可以确保在多个实例或服务器之间,相同任务在一个周期内只执行一次。以下是实现这一功能的步骤和示例代码:

步骤

  1. 选择分布式锁的实现:可以使用Redis、Zookeeper等来实现分布式锁。
  2. 获取锁:在任务开始执行之前尝试获取锁。如果成功获取到锁,则继续执行任务;如果没有获取到锁,则跳过执行。
  3. 释放锁:任务执行完毕后,释放锁,以便其他实例可以获取锁并执行任务。

示例代码(使用Redis作为分布式锁)

首先,添加Redis客户端依赖到你的项目中(例如使用Jedis):

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.0</version>
</dependency>

然后,创建一个使用Redis分布式锁的任务调度器:

import redis.clients.jedis.Jedis;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DistributedTaskScheduler {
   
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private final Jedis jedis = new Jedis("localhost", 6379); // 连接到Redis服务器

    public void start() {
   
        final Runnable task = () -> {
   
            String lockKey = "taskLock";
            long acquireTimeout = 5000; // 获取锁的超时时间(毫秒)
            long lockExpiry = 60000; // 锁的过期时间(毫秒)

            // 尝试获取锁
            if (acquireLock(lockKey, acquireTimeout, lockExpiry)) {
   
                try {
   
                    // 执行任务逻辑
                    System.out.println("Executing task at " + System.currentTimeMillis());
                } finally {
   
                    // 释放锁
                    releaseLock(lockKey);
                }
            } else {
   
                System.out.println("Failed to acquire lock, skipping task execution");
            }
        };
        // 每分钟检查一次是否需要执行任务
        scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.MINUTES);
    }

    private boolean acquireLock(String lockKey, long acquireTimeout, long lockExpiry) {
   
        long end = System.currentTimeMillis() + acquireTimeout;
        while (System.currentTimeMillis() < end) {
   
            if (jedis.setnx(lockKey, "locked") == 1) {
    // 尝试设置锁
                jedis.expire(lockKey, (int) (lockExpiry / 1000)); // 设置锁的过期时间
                return true;
            }
            try {
   
                Thread.sleep(100); // 等待一段时间后重试
            } catch (InterruptedException e) {
   
                Thread.currentThread().interrupt();
            }
        }
        return false;
    }

    private void releaseLock(String lockKey) {
   
        jedis.del(lockKey); // 删除锁
    }

    public static void main(String[] args) {
   
        DistributedTaskScheduler scheduler = new DistributedTaskScheduler();
        scheduler.start();
    }
}

在这个例子中,我们使用了Redis来存储锁的状态。acquireLock方法尝试获取锁,并在成功获取后设置一个过期时间,以防止死锁的情况发生。releaseLock方法用于释放锁。通过这种方式,我们可以确保在多个实例中,同一任务在一个周期内只被执行一次。

目录
相关文章
|
2月前
|
并行计算 算法 安全
【ADMM、碳排放】基于分布式ADMM算法的考虑碳排放交易的电力系统优化调度研究【IEEE6节点、IEEE30节点、IEEE118节点】(Matlab代码实现)
【ADMM、碳排放】基于分布式ADMM算法的考虑碳排放交易的电力系统优化调度研究【IEEE6节点、IEEE30节点、IEEE118节点】(Matlab代码实现)
110 0
|
2月前
|
机器学习/深度学习 并行计算 算法
基于目标级联法的微网群多主体分布式优化调度(Matlab代码实现)
基于目标级联法的微网群多主体分布式优化调度(Matlab代码实现)
|
2月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
162 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
3月前
|
边缘计算 运维 算法
含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)
含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)
|
4月前
|
人工智能 Java
Java多任务编排技术
JDK 5引入Future接口实现异步任务处理,但获取结果不够灵活。Java 8新增CompletableFuture,实现异步任务编排,支持流式处理、多任务组合及异常处理,提升执行效率与代码可读性,简化并发编程复杂度。
|
5月前
|
人工智能 Java Go
java判断ExecutorService是否有任务
在Java中,ExecutorService用于管理线程池。本文介绍如何判断ExecutorService是否有任务正在执行或等待执行。通过创建固定大小的线程池、提交任务,并使用`awaitTermination()`方法结合超时时间,可以有效检测任务状态。此方法简单实用,适用于多种场景。文末附有代码示例及详细解读。
|
7月前
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
253 5
|
7月前
|
SQL 监控 Go
新一代 Cron-Job分布式调度平台,v1.0.8版本发布,支持Go执行器SDK!
现代化的Cron-Job分布式任务调度平台,支持Go语言执行器SDK,多项核心优势优于其他调度平台。
118 8
|
8月前
|
测试技术 调度
新一代 Cron-Job分布式调度平台,v1.0.5版本发布!
增加标签路由能力和多项功能优化!其中Tag标签路由的功能,测试环境多迭代场景下,可通过给任务配置Tag标签,实现任务路由到不同的执行器上。
94 0