分布式锁的几种实现方式

本文介绍了分布式锁的三种常见实现方式:基于MySQL数据库的实现利用主键唯一性获取锁;Redis实现利用NX模式保证唯一性,但在高并发下需要注意连接问题;Zookeeper实现中通过不同节点类型解决并发问题,避免惊群现象。
摘要由CSDN通过智能技术生成

github源码下载

一.分布式锁的几种实现方式和对比

实现思路 优点 缺点
利用MySQL数据库实现

利用数据库自身提供的锁

要求数据库支持行级锁

实现简单,稳定可靠

性能差,无法适应高并发场景

容易出现死锁的的情况

无法优雅的实现阻塞式锁

利用缓存(redis)的实现方案

基于redis的setnx命令实现

并通过lua脚本保证解锁时对缓存操作序列的原子性

性能好

实现相对复杂

又出现死锁的可能性

无法优雅的实现阻塞式锁

利用zookeeper的实现方案 基于zk节点特性以及watch机制实现 性能好,稳定可靠性,能较好的实现阻塞式锁 实现相对复杂

    定义一个接口:

package com.roger.lock;

import java.util.concurrent.TimeUnit;

public interface DistributeLock {

    void lock(String lockKey,String lockValue);

    boolean tryLock(String lockKey,String lockValue);

    boolean tryLock(String lockKey,String lockValue,long time, TimeUnit timeUnit);

    boolean unLock(String lockKey,String lockValue);

}

二.分布式锁的具体实施方案

(1)利用MySQL数据库实现

实现思路:根据数据库表的主键唯一性特点,实现分布式锁,只要当insert成功后,才能获取到锁

package com.roger.lock.impl;

import com.roger.entity.DbDistriLock;
import com.roger.lock.DistributeLock;
import com.roger.mapper.DistributeLockMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service("dbLock")
public class DbLock implements DistributeLock {

    @Autowired
    private DistributeLockMapper distributeLockMapper;

    @Override
    public void lock(String lockKey, String lockValue) {
       if(!tryLock(lockKey,lockValue)){
           //无法优雅的阻塞自己 -- 线程沉睡500ms
           waitForLock();
           //再次去尝试获取锁,直到获取成功
           lock(lockKey,lockValue);
       }
    }

    private void waitForLock() {
        try {
            TimeUnit.MILLISECONDS.sleep(500);
        } catch (InterruptedException e) {

        }
    }

    @Override
    public boolean tryLock(String lockKey, String lockValue) {
        DbDistriLock dbDistriLock = new DbDistriLock();
        dbDistriLock.setId(lockKey);
        dbDistriLock.setDistributeLockName(lockValue);
        try {
            distributeLockMapper.insertDistributeLock(dbDistriLock);
        }catch (Exception e){
            return false;
        }
        return true;
    }

    @Override
    public boolean tryLock(String lockKey, String lockValue, long time, TimeUnit timeUnit) {
        if(tryLock(lockKey,lockValue)){
            return true;
        }

        if(time <= 0){
            return false;
        }

        long nanoTimes = tim
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值