Java并发:分布式锁(2)

if (jedis.setnx(lockKey, expiresStr) == 1) {
                // lock acquired
                locked = true;
                return true;
            }

String currentValueStr = jedis.get(lockKey); //redis里的时间
            if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
                //判断是否为空,不为空的情况下,如果被其他线程设置了值,则第二个条件判断是过不去的
                // lock is expired

String oldValueStr = jedis.getSet(lockKey, expiresStr);
                //获取上一个锁到期时间,并设置现在的锁到期时间,
                //只有一个线程才能获取上一个线上的设置时间,因为jedis.getSet是同步的
                if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
                    //如过这个时候,多个线程恰好都到了这里,但是只有一个线程的设置值和当前值相同,他才有权利获取锁
                    // lock acquired
                    locked = true;
                    return true;
                }
            }
            timeout -= 100;
            Thread.sleep(100);
        }
        return false;
    }

一般用法
其中很多繁琐的边缘代码
包括:异常处理,释放资源等等

JedisPool pool;
        JedisLock jedisLock = new JedisLock(pool.getResource(), lockKey, timeoutMsecs, expireMsecs);
        try {
            if (jedisLock.acquire()) { // 启用锁
                //执行业务逻辑
            } else {
                logger.info("The time wait for lock more than [{}] ms ", timeoutMsecs);
            }
        } catch (Throwable t) {
            // 分布式锁异常
            logger.warn(t.getMessage(), t);
        } finally {
            if (jedisLock != null) {
                try {
                    jedisLock.release();// 则解锁
                } catch (Exception e) {
                }
            }
            if (jedis != null) {
                try {
                    pool.returnResource(jedis);// 还到连接池里
                } catch (Exception e) {
                }
            }
        }

犀利用法
用匿名类来实现,代码非常简洁
至于SimpleLock的实现,请在我附件中下载查看

SimpleLock lock = new SimpleLock(key);
        lock.wrap(new Runnable() {
            @Override
            public void run() {
                //此处代码是锁上的
            }
        });

附件是分布式锁的完整实现和用法,有需要交流的朋友,可以随时留言。

------------------------------------------分割线------------------------------------------

免费下载地址在

用户名与密码都是

具体下载目录在 /2015年资料/1月/15日/Java并发:分布式锁

下载方法见

------------------------------------------分割线------------------------------------------

因为JAVA的实现和伪代码的实现有所不同,所以仔细对比了一下

伪代码是通过  当前时间  和  getset返回的库里面的时间对比  判断谁应该拿到锁。

JAVA实现是通过 对比两次get 和 getset的返回值的不同,来判断谁应该拿到锁。

两种实现在大多数情况都不会出问题,但是也有失败的情况

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/3ca61627f9f2d455a3e99c5790b67a4d.html