redis分布式锁

2017/10/27 分布式

Redis分布式锁概念很简单,通过Redis缓存唯一值大家都去抢,抢不到等会,抢到后同时设置失效时间执行完后把锁删除。

RedisLock

import org.springframework.data.redis.core.RedisTemplate;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * Created by litf on 2017/10/27.
 */

public class JedisLock {

    private RedisTemplate<String,String> template;


    private String keyName = "";
    private String keyValue = "";
    private long time = 0l;
    private boolean absent = false;

    private static final String KEY = ":lock_name";
    // 构造函数
    public JedisLock(){}
    // 私有构造函数初始化Key
    private JedisLock(String keyName,long time,String keyValue,RedisTemplate redisTemplate){
        this.keyName = keyName;
        this.time = time;
        this.keyValue = keyValue;
        this.template = redisTemplate;
    }

    // 创建对象供外部调用
    public static JedisLock newJedisLock(String keyName,long time,RedisTemplate redisTemplate){

        String keyValue = "";
        keyName = keyName+KEY;
        keyValue = UUID.randomUUID().toString();
        return  new JedisLock(keyName,time,keyValue,redisTemplate);

    }

    // 尝试获取锁
    public boolean tryLock(){
        absent =template.opsForValue().setIfAbsent(keyName,keyValue);

        if(absent){
            template.expire(keyName,time, TimeUnit.SECONDS);
        }
        return absent;
    }

    // 执行完记得解除
    public void unLock(){
        if (absent){
            System.out.println("unLock..."+keyName);
            template.delete(keyName);
        }
    }


}

测试代码

@Test
    public void JedisTest(){

        String keyName = "postPhone";
        // KEY失效时间
        long time = 10;
        // 三个任务
        final JedisLock lock1 = JedisLock.newJedisLock(keyName,time,template);
        final JedisLock lock2 = JedisLock.newJedisLock(keyName,time,template);
        final JedisLock lock3 = JedisLock.newJedisLock(keyName,time,template);

        Runnable runnable1 = new Runnable() {
            public void run() {
                while (true){
                    try{
                        // 每次抢之前休息5秒
                        TimeUnit.SECONDS.sleep(5);

                        System.out.println("R1-try");
                        // 获取锁
                        boolean absent = lock1.tryLock();
                        if(absent){
                            System.out.println("获取锁成功啦!R1..");
                        }else{
                            System.out.println("R1-faild");
                        }
                        // 模拟处理
                        TimeUnit.SECONDS.sleep(1);
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }finally {
                        lock1.unLock();
                    }
                }

            }
        };

        Runnable runnable2 = new Runnable() {
            public void run() {
                while(true){
                    try{
                        TimeUnit.SECONDS.sleep(5);

                        System.out.println("R2-try");
                        boolean absent = lock2.tryLock();
                        if(absent){
                            System.out.println("获取锁成功啦!R2");
                        }else{
                            System.out.println("R2-faild");
                        }
                        TimeUnit.SECONDS.sleep(1);
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }finally {
                        lock2.unLock();
                    }
                }

            }
        };

        Runnable runnable3 = new Runnable() {
            public void run() {
                while(true){
                    try{
                        TimeUnit.SECONDS.sleep(5);

                        System.out.println("R3-try");
                        boolean absent = lock3.tryLock();
                        if(absent){
                            System.out.println("获取锁成功啦!R3");
                        }else{
                            System.out.println("R3-faild");
                        }
                        TimeUnit.SECONDS.sleep(1);
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }finally {
                        lock3.unLock();
                    }
                }

            }
        };

        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(runnable1);
        executorService.execute(runnable2);
        executorService.execute(runnable3);
        // 跑两分钟
        try {
            TimeUnit.SECONDS.sleep(150L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.shutdown();

    }

执行结果


R3-try
R2-try
R1-try
R3-faild
R2-faild
获取锁成功啦!R1..
unLock...postPhone:lock_name
R3-try
获取锁成功啦!R3
R2-try
R1-try
R2-faild
R1-faild
unLock...postPhone:lock_name
R3-try
获取锁成功啦!R3
R2-try
R1-try
R1-faild
R2-faild
unLock...postPhone:lock_name
R3-try
R1-try
R2-try
获取锁成功啦!R3
R1-faild
R2-faild
unLock...postPhone:lock_name
R1-try
R2-try
R2-faild
获取锁成功啦!R1..
R3-try
R3-faild
unLock...postPhone:lock_name
R2-try
获取锁成功啦!R2
R3-try
R1-try
R3-faild
R1-faild
unLock...postPhone:lock_name
R2-try
R3-try
R1-try
R3-faild
R1-faild
获取锁成功啦!R2
unLock...postPhone:lock_name
R3-try
R1-try
R1-faild
获取锁成功啦!R3
R2-try
R2-faild
unLock...postPhone:lock_name
R1-try
R3-try
R1-faild
获取锁成功啦!R3
R2-try
R2-faild
unLock...postPhone:lock_name
R1-try
R3-try
获取锁成功啦!R1..
R3-faild
R2-try
R2-faild
unLock...postPhone:lock_name
R3-try
获取锁成功啦!R3
R1-try
R1-faild
R2-try
R2-faild


Show Disqus Comments

Search

    Post Directory