随笔 - 28  文章 - 0  评论 - 18 

使用Redis实现分布式锁

public class JedisLock {
    
    private Jedis jedis;
    
    private String lockKey;
    /**默认过期时间*/
    private int expireMillis = 3000;
    
    private String lockValue;
    
    public JedisLock(Jedis jedis, String lockKey){
        this.jedis = jedis;
        this.lockKey = lockKey;
    }
    
    
    public  boolean lock() throws InterruptedException{
        return lock(1);
    }
    
    public  boolean lock(int timeout) throws InterruptedException{
        while(timeout > 0){
            long expireTm = System.currentTimeMillis()+expireMillis;
            String expireTmStr = String.valueOf(expireTm);
            if(jedis.setnx(lockKey, expireTmStr)==1){
                lockValue = expireTmStr;
                return true;
            }
            String currentValueStr = jedis.get(lockKey);
            if(currentValueStr!=null && Long.parseLong(currentValueStr)<System.currentTimeMillis()){
                String oldValueStr = jedis.getSet(lockKey, expireTmStr);
                if(oldValueStr!=null && oldValueStr.equals(currentValueStr)){
                    lockValue = expireTmStr;
                    return true;
                }
            }
            timeout -= 100;
            Thread.sleep(100);
        }
        return false;
    }
    
    public  void unlock(){
        List<String> keys = new ArrayList<String>();
        keys.add(lockKey);
        List<String> args = new ArrayList<String>();
        args.add(lockValue);
    //采用lua脚本方式保证在多线程环境下也是原子操作 jedis.eval(
"if (redis.call('exists', KEYS[1]) == 0) then " + "return -1; " + "end;" + "if (redis.call('get', KEYS[1]) == ARGV[1]) then " + "redis.call('del', KEYS[1]); " + "return 1;" + "end; " + "return 0;" , keys, args); } }

 

posted on 2017-05-03 16:36  程序人生ly  阅读(276)  评论(0编辑  收藏