分布式锁的实现

1 Redisson组件



import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;

import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class RedissonManager {
 //#redisson config
//redisson.redis.urls=10.199.240.223:7000,10.199.240.223:7001,10.199.240.223:7002
	@Value(value = "${redisson.redis.urls}")
	private String nodeAddressStringList;

	private RedissonClient redissonClient;

	@PostConstruct
	private void initClient() {
		Config config = new Config();
		config.useClusterServers().setScanInterval(1000) // 集群状态扫描间隔时间,单位是毫秒
				.setIdleConnectionTimeout(10000) // 连接空闲超时,单位:毫秒
				.setPingTimeout(1000).setConnectTimeout(10000) // 连接超时,单位:毫秒
				.setTimeout(3000) // 命令等待超时,单位:毫秒
				.setRetryAttempts(3) // 命令失败重试次数
				.setSubscriptionsPerConnection(5) // 单个连接最大订阅数量
				.setSlaveSubscriptionConnectionMinimumIdleSize(1) // 从节点发布和订阅连接的最小空闲连接数
				.setSlaveSubscriptionConnectionPoolSize(50) // 从节点发布和订阅连接池大小
				.setReconnectionTimeout(3000) // 重新连接时间间隔,单位:毫秒
				.setMasterConnectionPoolSize(64) // 主节点连接池大小
				.setMasterConnectionMinimumIdleSize(10) // 主节点最小空闲连接数
				.setSlaveConnectionPoolSize(64) // 从节点连接池大小
				.addNodeAddress(nodeAddressStringList.split(","));
		redissonClient = Redisson.create(config);
	}

	/**
	 * 获取名称对应的锁
	 *
	 * @param objectName
	 * @return
	 */
	public RLock getRLock(String objectName) {
		RLock rLock = redissonClient.getLock(objectName);
		return rLock;
	}



    /**
     * redisson释放锁
	 *
	 * @param rLock
	 */
	public void unLock(RLock rLock) {
		if (rLock == null) {
			return;
		}
		try {
			rLock.unlock();
		} catch (Exception e) {
			LOG.error("释放锁失败", e);
		}
	}
}

总结:Redisson还有其他获得锁的方式,具体参考官方文档

2 zookeeper实现分布式锁

@Configuration
@Slf4j
public class RedissonManagerConfig {

    @Value("${spring.redisson.urls}")
    private String redisHostAndPort;

    @Bean
    @Profile("prod")
    public RedissonClient redissonClientCluster() throws IOException {
        String[] nodes = redisHostAndPort.split(",");
        for (int i = 0; i < nodes.length; i++) {
            nodes[i] = "redis://" + nodes[i];
        }
        Config config = new Config();
        config.useClusterServers().setScanInterval(2000).addNodeAddress(nodes);
        RedissonClient redissonClient = Redisson.create(config);
        log.info("redissonClient初始化成功, 配置信息[{}]",redissonClient.getConfig().toJSON());
        return redissonClient;
    }

    @Bean
    @Profile({"dev","test","sit","uat","prf"})
    public RedissonClient redissonClientSingle() throws IOException {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://"+ redisHostAndPort);
        RedissonClient redissonClient = Redisson.create(config);
        log.info("redissonClient初始化成功, 配置信息[{}]",redissonClient.getConfig().toJSON());
        return redissonClient;
    }
}
/**
 * Redisson客户端实现分布式锁
 * @author huangliang
 * @date 2019-09-10
 *
 */
@Slf4j
public class RedissonLockUtil {

	public static RedissonClient getRedissonClient(){
		return SpringHelper.getBean(RedissonClient.class);
	}

	/**
	 * 获取锁,线程获取不到锁就一直block
	 * @param lockKey
	 * @return
	 */
	public static RLock lock(String lockKey){
		RLock lock = getRedissonClient().getLock(lockKey);
		lock.lock();
		return lock;
	}

	/**
	 *
	 * @param lockKey
	 * @param leaseTime 加锁时间 单位毫秒
	 * @return
	 */
	public static RLock lock(String lockKey,long leaseTime){
		RLock lock = getRedissonClient().getLock(lockKey);
		lock.lock(leaseTime,TimeUnit.MILLISECONDS);
		return lock;
	}

	/**
	 *
	 * @param lockKey
	 * @param leaseTime 加锁时间
	 * @param unit  时间单位
	 * @return
	 */
	public static RLock lock(String lockKey,long leaseTime,TimeUnit unit){
		RLock lock = getRedissonClient().getLock(lockKey);
		lock.lock(leaseTime,unit);
		return lock;
	}

	/**
	 * 尝试获取锁
	 * @param lockKey
	 * @param leaseTime 加锁时间
	 * @param waitTime 等待时间
	 * @param unit 时间单位
	 * @return
	 */
	public static boolean tryLock(String lockKey,long leaseTime,long waitTime,TimeUnit unit){
		RLock lock = getRedissonClient().getLock(lockKey);
		try {
			return lock.tryLock(waitTime,leaseTime,unit);
		} catch (InterruptedException e) {
			log.info("获取锁发生异常",e);
			return false;
		}
	}

	/**
	 * 尝试获取锁
	 * @param lockKey
	 * @param waitTime 等待时间
	 * @param unit 时间单位
	 * @return
	 */
	public static boolean tryLock(String lockKey,long waitTime,TimeUnit unit){
		RLock lock = getRedissonClient().getLock(lockKey);
		try {
			return lock.tryLock(waitTime,unit);
		} catch (InterruptedException e) {
			log.info("获取锁发生异常",e);
			return false;
		}

	}

	/**
	 * 释放锁
	 * @param lockKey
	 */
	public static void unlock(String lockKey){
		RLock lock = getRedissonClient().getLock(lockKey);
		if (lock != null && lock.isHeldByCurrentThread()) {
			lock.unlock();
		}

	}

	/**
	 * 释放锁
	 * @param lock
	 */
	public static void unlock(RLock lock){
		if (lock != null && lock.isHeldByCurrentThread()) {
			lock.unlock();
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值