Fork me on GitHub
AlbertWei's Blogs

Record the challenage met in work


  • 首页

  • 归档

redis做分布式锁的实现

发表于 2017-11-12

Redis实现分布式锁

一.主要用到的函数

1.setNX(key, value): 如果key不存在的设置value值,否则就不设置,设置成功则返回1,设置失败则返回0。
2.getSet:获得设置之前的值并给其设置新的值。

二.redis锁实现原理

1.在第一个线程进来的时候调用setNX方法设置名称和对应的时间戳加过期时间
jedis.setNX("redisKey", System.currentTimeMillis() + expireTime)

2.在第二个线程进来的时候调用setNX方法时如果返回1则说明上一个线程已经执行完成了,redis锁已经被释放了,如果返回0则说明锁没有被释放,则可以等待或者重试

3.具体代码实现(这里面有个防止线程饥饿的判断,没弄懂啥意思)
//加锁的代码实现
public synchronized boolean lock() {
    int timeout = this.timeout;
    long expires = System.currentTimeMillis() + expire + 1;
    String expiresStr = String.valueOf(expires) + ";" + hostName; 
    //如果设置成功了则返回1
    if(jedis.setNX(lockKey, expiresStr) == 1){
        return true;
    }else {
        //从redis中获得过期时间
        String oldValue = jedis.get(lockKey);
        if(oldValue < System.currentMillis){
            //说明已经过期了,可以获得锁
            String currentTime = jedis.getSet(lockKey,
            System.currentTimeMillis() + expire + 1);
            //由于getSet()是同步的所以返回的值一定是最新的一个
            //比较currentTime和oldValue的值,如果不相同的话说明此时被其他的线程改篡改了
            if(currentTime.equals(oldValue)){
                //说明没有被篡改,此时的锁已经过期了
                return true;
            }else {
                return false;
            }
        }else {
            //没有过期
            return false;                
        }
    }
}
//释放锁的代码实现
public sychronized boolean unlock() {
    jedis.delete(lockKey);
}

详细实现代码:https://www.cnblogs.com/SimplifyIT/p/6691584.html

浅谈HashMap,HashTable和concurrentHashMap的区别

发表于 2017-11-03

HashMap

一.定义

HashMap的数据结构为数组加链式的。
存值的时候根据key值计算出其hashCode的值然后对应数组的索引(索引上存的是一个entry),如果多个不同的key得到的hashCode值相同的话,则存储在数组对应的链上,新插入的(entry)在链的前面。
取值的时候根据key计算出对应的hashCode,找到数组上的索引,然后遍历此索引上的entry链,取出对应的key的value值。

二.ConcurrentHashMap和HashTable的区别

相同点:HashTable和ConcurrentHashMap都是线程安全的,可以适用于高并发的环境。
不同点:HashTable没有使用分段锁的机制,在迭代的时候会将整个map集合都锁定,ConcurrentHashMap使用了分段锁的机制,在迭代时只会锁定map的部分。HashTable防止并发的处理就是在每一个方法上都加了同步锁机制。

三.HashMap并发导致的原因

在hashmap的长度达到零界并准备扩容的时候会调用一个transfer的方法,这个方法中迭代时由于next的值被另外一个线程给改变了,会导致死循环(具体也没咋看明白)
详细请见:https://blog.csdn.net/dgutliangxuan/article/details/78779448
12
AlbertWei

AlbertWei

Record the challenage met in work

12 日志
友情链接
  • xiongyufeng的博客
© 2018 AlbertWei
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4