redis分布式锁

package com.paic.pscp.ejb.ejbmgr.biz.util;


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import com.paic.pscp.manager.common.util.LogRecorder;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisException;


/**
 * Redis实现分布式锁
 */
public class RedisLock {

    /**
     * Logger
     */
	private static LogRecorder logUtil = LogRecorder.getInstance();
	/**
     * 
     * 
     * @param lockKey 锁key
     * @param expireTime 自动释放锁时间,单位秒
     * @param timeout 取锁超时时间,单位毫秒
     * @return
     */
    public boolean lock(final String lockKey, final int expireTime, final long timeout) {
   
    	logUtil.info("RedisLock[{1}]try lock! lockKey="+lockKey+",expireTime"+expireTime+" ,timeout"+timeout);
                boolean locked = false;
                long now = System.nanoTime();

                do {
                    try {
                        String value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
                            .format(new Date())
                                       + "_"
                                       + Thread.currentThread().getName()
                                       + "_"
                                       + UUID.randomUUID().toString();

                        long lock = JedisUtil.setnx(lockKey, value);

                        logUtil.info("RedisLock[{2}]Setnx result"+lock+", value:"+value);
                        
                        locked = (1 == lock);
                        if (locked) {//首次进入的锁设置过期时间
                        	return JedisUtil.expire(lockKey, expireTime);
                        } else {
                            String ctx = JedisUtil.get(lockKey);
                            Long expire = JedisUtil.ttl(lockKey);
                            logUtil.info("RedisLock[{3}] Lock key:"+lockKey+", value:"+ctx+", expireTime:"+ expire);
                            
                            // 如果没有设置超时时间,则设置为当前的超时时间
                            if(expire == -1) {
                            	JedisUtil.expire(lockKey, expireTime);
                            }
                        }
                    } catch (JedisException e) {
                        // redis操作异常
                    	logUtil.error(getClass(), "lock()", "[{2}] 操作Redis锁失败 lockkey = {"+lockKey+"}", e, "JedisException");
                        continue;
                    } catch (Exception e) {
                    	logUtil.error(getClass(), "lock()", "[{2}] 操作Redis锁失败 lockkey = {"+lockKey+"}", e, "RedisLock");
                    }

                } while (!locked && (System.nanoTime() - now < timeout * 1000));

                logUtil.info("RedisLock[{2}] try lock finished! lockKey="+lockKey+", locked={"+locked+"}");
                return locked;
            }
        
    

    /**
     * 
     * 
     * @param lockKey  锁key
     * @param timeout 释放锁超时时间, 单位毫秒
     * @return
     */
    public boolean unLock(final String lockKey, final long timeout) {
  
    	logUtil.info("RedisLock[{1}]try lock! lockKey="+lockKey+" ,timeout"+timeout);
                long now = System.nanoTime();
                do {
                    try {
                        long lock = JedisUtil.del(lockKey);
                        return 1 == lock;
                    } catch (Exception e) {
                        // redis操作异常
                        logUtil.error(this.getClass(),"unLock()","[{1}] 操作Redis锁失败 lockkey = {"+lockKey+"}" ,e,"RedisLock");
                        continue;
                    }
                } while (System.nanoTime() - now < timeout * 1000);

                logUtil.info("RedisLock[{1}] unlock success! lockKey={"+lockKey+"}");
                return false;
            }
        
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值