码迷,mamicode.com
首页 > 其他好文 > 详细

redis锁

时间:2017-11-02 20:01:37      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:his   ack   read   long   ram   redislock   休眠   style   oid   

拓展 ycgwl-cache RedisStorage

/**
     * 如果不存在则 写入缓存并设置过期时间
     * @param key
     * @param value
     * @param expire
     * @return
     */
    public Long setnx(String key, V value,int expire) {
        Jedis j = null;
        String svalue = JsonUtils.toJsonString(value);
        boolean borrowOrOprSuccess = true;

        try {
            j = this.client.getResource();
            Long setnx = j.setnx(key, svalue);
            j.expire(key, expire);

            return setnx;

        } catch (JedisException var10) {
            borrowOrOprSuccess = false;
            if (j != null) {
                this.client.returnBrokenResource(j);
            }

            LOG.error(var10.getMessage(), "EXCEPTION", var10);
        } finally {
            if (borrowOrOprSuccess) {
                this.client.returnResource(j);
            }

        }
        return 0L;
    }

base-dev-service-impl 添加 RedisLock

package lock.lock;

import com.ycgwl.cache.storage.RedisStorage;

import java.util.Random;


public class RedisLock {

    //纳秒和毫秒之间的转换率
    public static final long MILLI_NANO_TIME = 1000 * 1000L;

    //表示被锁定的 value 值
    public static final String LOCKED = "TRUE";
    
    public static final Random RANDOM = new Random();

    //reids key
    private String key;

    //封装的操作redis的工具
    private RedisStorage storage;

    //是否锁定成功
    private boolean lock = true;

    
    public RedisLock(String purpose, String key, RedisStorage storage){
        this.key = purpose + "_" + key + "_lock";
        this.storage = storage;
   }
    
    /**
     * 加锁
     * 使用方式为:
     * lock();
     * try{
     *       executeMethod();
     * }finally{
     *      unlock();
     * }
     * @param timeout timeout的时间范围内轮询锁 纳秒
     * @param expire 设置锁超时时间  秒
     * @return 成功 or 失败
     */
    public boolean lock(long timeout,int expire){

        //获取当前纳秒级时间
        long nanoTime = System.nanoTime();

        //超时时间转纳秒
        timeout *= MILLI_NANO_TIME;
        try {
            //在timeout的时间范围内不断尝试写入锁
            while (System.nanoTime() - nanoTime < timeout) {
                //锁不存在的话,设置锁并设置锁过期时间,即加锁
                if (this.storage.setnx(this.key, LOCKED,expire) == 1) {
                    //设置锁过期时间是为了在没有释放锁的情况下锁过期后消失,不会造成永久阻塞
                    this.lock = true;
                    return this.lock;
                }
                //短暂休眠,避免可能的活锁
                Thread.sleep(3, RANDOM.nextInt(30));
            } 
        } catch (Exception e) {
            throw new RuntimeException("获取锁失败",e);
        }
        return false;
    }

    /**
     * 解锁
     */
    public  void unlock() {
        try {
            if(this.lock){
                storage.remove(key);//直接删除
            }
        } catch (Throwable e) {
            throw new RuntimeException("删除锁失败",e);
        }
    }

}

 

 原始方法改私有

新添加加锁接口

    @Resource
    private RedisStorage storage;

    @Override
    public void updateOrderByLock(Long id){
        RedisLock redisLock = new RedisLock("BaseSiteEntity_SiteId", id + "", this.storage);
        boolean result = redisLock.lock(2000, 10);
        //取锁失败
        if(!result){
            throw new RuntimeException("id:"+id+" 获取锁失败");
        }
        try{
            //执行方法
             updateOrderBy(id);
        }finally{
            //释放锁
            redisLock.unlock();
        }

    }

 其他  http://www.cnblogs.com/zfzf1/p/7768211.html

技术分享

 

redis锁

标签:his   ack   read   long   ram   redislock   休眠   style   oid   

原文地址:http://www.cnblogs.com/zfzf1/p/7773817.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!