使用redis实现分布式锁

来源:互联网 发布:人大经济论坛数据库 编辑:程序博客网 时间:2024/05/16 08:13

核心是使用redis的setnx操作

Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。redis的SETNX命令可以方便的实现分布式锁。

2、基本命令解析

1)setNX(SET if Not eXists)

语法:

SETNX key value

将 key 的值设为 value ,当且仅当 key 不存在。

若给定的 key 已经存在,则 SETNX 不做任何动作。

SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写

返回值:

  设置成功,返回 1 。
  设置失败,返回 0 。


package redis;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.ThreadFactory;import java.util.concurrent.atomic.AtomicInteger;import redis.clients.jedis.Jedis;/** * 模拟分布式并发 *  * 使用redis的setnx来实现 * 如果有某个key就不能set */public class LockTest {private Jedis jedisCli = new Jedis("localhost",6379);    public boolean lock(String lockID){    // 一直尝试找到成功为止        while(true){            long flag = jedisCli.setnx(lockID, "1");            if(flag == 1) {            System.out.println(Thread.currentThread().getName() + " get lock .... ");            return true;            }            System.out.println(Thread.currentThread().getName() + " is trying lock ... ");                        try {            Thread.sleep(2000);            } catch (Exception e) {e.printStackTrace();return false;}        }    }        public void unlock(String lockId) {    long flag = jedisCli.del(lockId);        if (flag>0){            System.out.println(Thread.currentThread().getName() + " release lock....");        }else {            System.out.println(Thread.currentThread().getName() + " release lock fail....");        }    }                /**     * 线程工厂,命名线程     */    public static class MyThreadFactory implements ThreadFactory{        public static AtomicInteger count = new AtomicInteger();        @Override        public Thread newThread(Runnable r) {            count.getAndIncrement();            Thread thread = new Thread(r);            thread.setName("Thread-lock-test "+count);            return thread;        }    }            public static void main(String[] args) {    // 就是通过这个String作为key来处理并发的final String lockID = "test";MyThreadFactory factory = new MyThreadFactory();ExecutorService es = Executors.newFixedThreadPool(10);for(int i=0; i<10; i++)es.execute(factory.newThread(new Runnable(){@Overridepublic void run() {// 模拟并发LockTest testCli = new LockTest();testCli.lock(lockID);try {                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }            testCli.unlock(lockID);}}));}}



原创粉丝点击