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; }