redis分布式锁

来源:互联网 发布:韩信厉害知乎 编辑:程序博客网 时间:2024/05/22 11:01
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;            }            }

0 0