Redis实现分布式锁

通过Redis实现分布式锁,主要使用了如下命令:

SETNX key val
当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。

expire key timeout
为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。

delete key 
删除key

实现使用的是jedis来连接Redis。

建立一个MAVEN工程,然后,pom文件引入jedis

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.0</version>
</dependency>

核心代码如下:

package redis.test.redislock;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class DistributedLock
{
    private final JedisPool jedisPool;
    private final String LOCK_NAME = "redisLock";
    
    public DistributedLock(JedisPool jedisPool)
    {
        this.jedisPool = jedisPool;
    }
    
    public long getLock(String lockValue)   
    {
        Jedis jedis = null;
        long exist = 0;
        try
        {
            jedis = jedisPool.getResource();
            exist = jedis.setnx(LOCK_NAME, lockValue);
        }
        finally
        {
            if(jedis != null)
            {
                jedis.close();
            }
        }
        return exist;
    }
    
    public String getLockValue()
    {
        String name = "";
        Jedis jedis = null;
        try
        {
            jedis = jedisPool.getResource();
            name = jedis.get(LOCK_NAME);
        }
        finally
        {
            if(jedis != null)
            {
                jedis.close();
            }
        }
        return name;
    }
    
    public long expireTime(int expireTime)
    {
        long isSuccess = 0;
        Jedis jedis = null;
        try
        {
            jedis = jedisPool.getResource();
            isSuccess = jedis.expire(LOCK_NAME, expireTime);
        }
        finally
        {
            if(jedis != null)
            {
                jedis.close();
            }
        }
        return isSuccess;
    }
    
    public long releaseLock(String lockValue)
    {
        long isSuccess = 0;
        Jedis jedis = null;
        try
        {
            jedis = jedisPool.getResource();
            jedis.watch(LOCK_NAME);
            if(lockValue.equals(jedis.get(LOCK_NAME)))
            {
                isSuccess = jedis.del(LOCK_NAME);
            }
            
        }
        finally
        {
            if(jedis != null)
            {
                jedis.close();
            }
        }
        return isSuccess;
    }
}

测试Demo

package redis.test.redislock;

import redis.clients.jedis.JedisPool;

public class TestLock implements Runnable
{
    public static void main(String[] args)
    {
       
        TestLock testLock = new TestLock();
        for (int i = 0; i < 50; i++) {
            Thread threadA = new Thread(testLock);
            threadA.start();
        }
    }

    public void run()
    {
        JedisPool jedisPool = new JedisPool("10.185.156.190", 6379);
        DistributedLock distributedLock = new DistributedLock(jedisPool);
        
        if(1 == distributedLock.getLock(Thread.currentThread().getName()))
        {
            System.out.println("set expire time : " + (1 == distributedLock.expireTime(1000)));
            System.out.println("get value : " + distributedLock.getLockValue());
            distributedLock.releaseLock(Thread.currentThread().getName());
        }
        else 
        {
            System.out.println("get lock fail.");
        }
        
    }
}

 

posted @ 2018-09-08 17:32  woniu4  阅读(148)  评论(0编辑  收藏  举报