欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于redis setnx命令的分布式锁 redis 

程序员文章站 2022-07-14 12:24:55
...
public class SoaLockSupport {

	private Logger logger = Logger.getLogger(SoaLockSupport.class);
        
        //你的redis实现类
	private RedisAAA redis;

	// 超时时间
	private long timeout = 3000;
	
	/**
	 * 获得锁,如果没拿到,会在超时时间内一直等待
	 */
	public boolean lock(final String key) {
		FutureTask<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>() {
			public Boolean call() {
				boolean nx = false;
				for (;;) {
					nx = setnx(key);
					if(nx){
						break;
					}
					try {
						// 获取不到暂停2ms
						Thread.sleep(2);
					} catch (InterruptedException e) {
						//
					}
				}
				return nx;
			}
		});
		try {
			return future.get(timeout, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			logger.error("try lock error,key = "+key, e);
		}
		
		return false;
	}

	/**
	 * 尝试获得锁,如果没拿到,直接返回失败
	 */
	public boolean trylock(String key) {
		if (setnx(key)) {
			return true;
		}

		// 做这一步是防止key一直不被Delete,导致锁一直得不到释放的问题
		String oldTime = redis.getString(key);
		if (oldTime != null && !oldTime.equals("")) {
			long time = Long.valueOf(oldTime) + timeout;
			long now  = System.currentTimeMillis();
			
			if (time < now) {
				logger.info("time = "+time + ",and now="+now);
				redis.delete(key);
				return setnx(key);
			}
		}
		return false;
	}

	/**
	 * 释放锁
	 */
	public void unlock(String key) {
		redis.delete(key);
	}

	private boolean setnx(String key) {
		if (redis.setnx(key, System.currentTimeMillis() + "") == 1) {
			return true;
		}
		return false;
	}

 

相关标签: redis