redis 设置分布式锁

    public static boolean acquireLock(String lock) {
      // 1. 通过SETNX试图获取一个lock
      boolean success = false;
      Jedis jedis = pool.getResource();
      long value = System.currentTimeMillis() + expired + 1;
      System.out.println(value);
      long acquired = jedis.setnx(lock, String.valueOf(value));
      //SETNX成功,则成功获取一个锁
      if (acquired == 1)
         success = true;
         //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时
      else {
         long oldValue = Long.valueOf(jedis.get(lock));

         //超时
         if (oldValue < System.currentTimeMillis()) {
            String getValue = jedis.getSet(lock, String.valueOf(value));
            // 获取锁成功
            if (Long.valueOf(getValue) == oldValue)
               success = true;
               // 已被其他进程捷足先登了
            else
               success = false;
         }
         //未超时,则直接返回失败
         else
            success = false;
      }
      pool.returnResource(jedis);
      return success;
   }

   //释放锁
   public static void releaseLock(String lock) {
      Jedis jedis = pool.getResource();
      long current = System.currentTimeMillis();
      // 避免删除非自己获取得到的锁
      if (current < Long.valueOf(jedis.get(lock)))
         jedis.del(lock);
      pool.returnResource(jedis);
   }



//--------------------------

   public Long acquireLock(final String lockName,final long expire){
      return redisTemplate.execute(new RedisCallback<Long>() {
         public Long doInRedis(RedisConnection connection) {
            byte[] lockBytes = redisTemplate.getStringSerializer().serialize(lockName);
            boolean locked = connection.setNX(lockBytes, lockBytes);
            connection.expire(lockBytes, expire);
            if(locked){
               return 1L;
            }
            return 0L;
         }
      });
   }


//原子操作 -----------------------

   public String getAndSet(final String key,final String value){
      return  redisTemplate.execute(new RedisCallback<String>() {
         @Override
         public String doInRedis(RedisConnection connection)
               throws DataAccessException {
            byte[] result = connection.getSet(redisTemplate.getStringSerializer().serialize(key),
                  redisTemplate.getStringSerializer().serialize(value));
            if(result!=null){
               return new String(result);
            }
            return null;
         }
      });
   }

来自:http://www.blogjava.net/hello-yun/archive/2014/01/15/408988.html

应用:

/**
 * 使用数据同步锁
 * @param lock  * @param bBlackout 是否中断
 * @return
 */
public boolean acquireLock(String lock, boolean bBlackout) {
    // 1. 通过SETNX试图获取一个lock
    boolean success = false;
    Jedis jedis = CacheService.getInstance().getJedis();

    while (!success) {
        long value = System.currentTimeMillis() + 3000 + 1;
        long acquired = jedis.setnx(lock, String.valueOf(value));
        //SETNX成功,则成功获取一个锁
        if (acquired == 1)
            success = true;
            //SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时
        else {
            long oldValue = Long.valueOf(jedis.get(lock));

            //超时
            if (oldValue < System.currentTimeMillis()) {
                String getValue = jedis.getSet(lock, String.valueOf(value));
                // 获取锁成功
                if (Long.valueOf(getValue) == oldValue)
                    success = true;
                    // 已被其他进程捷足先登了
                else
                    success = false;
            }
            //未超时,则直接返回失败
            else
                success = false;
        }

        // 如果是非中断模式,则不用继续
        if ( !bBlackout )
            break;

        // 如果没拿到锁,则等待50毫秒
        if (!success){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    jedis.close();

    return success;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值