前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式锁的实现

分布式锁的实现

作者头像
Monica2333
发布2020-06-19 17:54:41
4200
发布2020-06-19 17:54:41
举报

1.什么是分布式锁

锁是为了保证在多线程并发的情况下,只有一个线程执行同步代码块。在一个JVM进程中,可通过synchronized 或者 J.U.C包中的显示并发锁保证。分布式锁就是多个进程一次只能有一个进程(或线程)执行同步代码块。

2.分布式锁的实现

可以采用框架的实现方式,如Memcached的原子性操作add命令、redis的setnx命令和lua脚本、zookeeper的顺序临时节点等来保证。 redis实现方案: 加锁操作

    /**
     * try get distributed lock
     * @param lockKey
     * @param requestId:锁的value值
     * @param expireTime TimeUnit seconds
     * @return Whether or not to get the lock successfully
     */
 public boolean tryGetDistributedLock(String lockKey, String requestId, long expireTime)  {
        boolean result = false;
        try {
            // 保证原子性,取锁由一条命令完成
            String response = jedisCluster.set(lockKey, requestId, "NX", "PX", expireTime*1000);
            if(LOCK_SUCCESS.equals(response))  {
                result = true;
            }
        }
        catch (Exception e) {
            log.error("Try get distributed lock:[lockKey:{0}, requestId:{1}] error due to {2}.", lockKey, requestId, e);
        }
        return result;
    }

解锁操作

 public boolean releaseDistributedLock(String lockKey, String requestId) {
        boolean result = false;
        try {
            // 保证原子性,解锁由一条命令完成
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            Object response = jedisCluster.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
            if (RELEASE_SUCCESS.equals(response))  {
                return true;
            }
        }
        catch (Exception e)  {
            log.error("Release distributed lock:[lockKey:{0}, requestId:{1}] error due to {2}.", lockKey, requestId, e);
        }
        return result;
    }

requestId的值最好设置为与线程相关,这样保证只有获得该锁的线程可以释放锁。 如果加锁之后的业务事情还没有完成,但是持有锁的事件超过了 expireTime ,此时锁被释放,仍不能完全保证同步代码块的执行。解决方案:可将expireTime 设置的长些,或者在加锁线程内开启一个守护线程,为锁续命。。

zookeeper 使用curator框架

InterProcessMutex lock = new InterProcessMutex(client, lockPath);
if ( lock.acquire(maxWait, waitUnit) ) {
    try {
        // do something
    }
    finally {
        lock.release();
    }
}

参考文章: 基于Zookeeper的分布式锁

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.什么是分布式锁
  • 2.分布式锁的实现
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档