乐趣区

Redis分布式锁

Redis 实现的分布式锁,jedis-2.9.0.jar 以上版本。commons-pool2-2.4.2.jar 以上版本

import java.util.Collections;
import javax.annotation.PostConstruct;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class RedisDistributedLock {

    private static volatile JedisPool jedisPool;
    private static final String PREFIX = "redis_lock_";
    private static final Long RELEASE_SUCCESS = 1L;
    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final String RELEASE_LOCK_SCRIPT = "if redis.call(\'get\', KEYS[1]) == ARGV[1] then return redis.call(\'del\', KEYS[1]) else return 0 end";

    @PostConstruct
    public void initJedis() {loadJedis();
    }
    
    private synchronized void loadJedis() {if (jedisPool == null) {
            int timeout = 1000 * 30;
            GenericObjectPoolConfig config = new GenericObjectPoolConfig();
            config.setMaxTotal(120);
            config.setMaxIdle(50);
            config.setMaxWaitMillis(10000);
            config.setTestOnBorrow(true);
            jedisPool = new JedisPool(config, "127.0.0.1", 6379, timeout, "123456");
        }
    }

    /**
     * 返还到连接池
     * 
     * @param pool
     * @param redis
     */
    public void close(Jedis redis) {if (redis != null) {redis.close();
        }
    }

    /**
     * @param lockKey 分布式锁的 key
     * @param lockVal 分布式锁得 value
     * @param expiredMilliSeconds key 的超时时间
     * @param maxWaitMilliSeconds 获取锁的最大超时时间
     * @return
     */
    public boolean tryLock(String lockKey, String lockVal, long expiredMilliSeconds, long maxWaitMilliSeconds) {long tryLockTime = System.currentTimeMillis();

        while (!tryLock(lockKey, lockVal, expiredMilliSeconds)) {if (System.currentTimeMillis() - tryLockTime > maxWaitMilliSeconds) {return false;}

            try {Thread.sleep(10L);
            } catch (InterruptedException arg9) {}}

        return true;
    }

    private boolean tryLock(String lockKey, String lockVal, long expiredMilliSeconds) {
        Jedis jedis = null;
        try {jedis = jedisPool.getResource();
            String result = jedis.set(PREFIX + lockKey, lockVal, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expiredMilliSeconds);
            return LOCK_SUCCESS.equals(result);
        } catch (Exception e) { } finally {close(jedis);
        }
        return false;
    }

    public boolean unlock(String lockKey, String lockVal) {
        Jedis jedis = null;
        try {jedis = jedisPool.getResource();
            Object result = jedis.eval(RELEASE_LOCK_SCRIPT, Collections.singletonList(lockKey),
                    Collections.singletonList(lockVal));
            return RELEASE_SUCCESS.equals(result);
        } catch (Exception e) { } finally {close(jedis);
        }
        return false;
    }
}
退出移动版