redis分布式锁练习【我】

 

package redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisLock {

    public static void main(String[] args) {
        
        JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
        // 从连接池中获取一个jedis对象
        Jedis jedis = jedisPool.getResource();
        
        //简单加redis分布式锁的方式
        boolean lock = false;
        String key = "mylock";
        String value = System.currentTimeMillis()+"";
        
        try {
            //50秒自动解锁
            String setResult = jedis.set(key,value , "nx", "ex", 50L);
            long startTime = 0;
            if (setResult!=null) {
                lock = true;
                startTime = System.currentTimeMillis();
            }
            
            //没有获取到锁,退出
            if (!lock) {
                return;
            }
            
            //执行到了这一步说明已经获取到锁 
            //        doSth
            
            long endTime = System.currentTimeMillis();
            //如果超时解锁
            if ((endTime-startTime)>5000) {
                //打印日志
                System.out.println("出现超时解锁-----------key:"+key);
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //这里是为了避免超时后,释放掉其他线程的同名锁
            //但是有个问题,就是下面的代码不是原子操作,可能会有问题,这里忽略
            String s = jedis.get(key);
            if (value.equals(s)) {
                //释放锁
                jedis.del(key);
            }
        }
        
        
        
        
        
        
        
        
        
        
        
    }
}

 

 

 

 

package redis;

import java.util.HashMap;
import java.util.Map;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisReentrantLock {

    
    private ThreadLocal<Map<String,Integer>> lockers =  new ThreadLocal<>();
    private Jedis jedis;
    
    public RedisReentrantLock(Jedis jedis) {
        super();
        this.jedis = jedis;
    }

    private boolean _lock(String key) {
        return jedis.set(key,"" , "nx", "ex", 5L)!=null;
    }
    
    private void _unlock(String key) {
        jedis.del(key);
    }
    
    private Map<String, Integer> currentLockers(){
        Map<String, Integer> refs = lockers.get();
        if (refs !=null) {
            return refs;
        }
        lockers.set(new HashMap<String, Integer>());
        return lockers.get();
    }
    
    public boolean lock(String key) {
        Map<String, Integer> refs = currentLockers();
        Integer refCnt = refs.get(key);
        if (refCnt!=null) {
            refs.put(key, refCnt+1);
            return true;
        }
        boolean ok = this._lock(key);
        if (!ok) {
            return false;
        }
        
        refs.put(key, 1);
        return true;
    }
    
    public boolean unlock(String key) {
        Map<String, Integer> refs = currentLockers();
        Integer refCnt = refs.get(key);
        if (refCnt == null) {
            return false;
        }
        refCnt -= 1;
        if (refCnt>0) {
            refs.put(key, refCnt);
        }else {
            refs.remove(key);
            this._unlock(key);
        }
        return true;
    }
    
    
    public static void main(String[] args) {
        JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
        // 从连接池中获取一个jedis对象
        Jedis jedis = jedisPool.getResource();
        RedisReentrantLock redisLock = new RedisReentrantLock(jedis);
        System.out.println(redisLock.lock("lock1"));
        System.out.println(redisLock.lock("lock1"));
        System.out.println(redisLock.unlock("lock1"));
        System.out.println(redisLock.unlock("lock1"));
    }
    
}

 

posted @ 2019-08-01 18:13  戈博折刀  阅读(252)  评论(0编辑  收藏  举报