redis实战教程(一)-分布式锁
来源:互联网 发布:手机淘宝怎么查看消费 编辑:程序博客网 时间:2024/05/21 09:52
主要用到setnx函数,原理如下:
命令格式
SETNX key value
将 key 的值设为 value,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。
SETNX 是SET if Not eXists的简写。
返回值
返回整数,具体为
- 1,当 key 的值被设置
- 0,当 key 的值没被设置
例子
redis> SETNX mykey “hello”
(integer) 1
redis> SETNX mykey “hello”
(integer) 0
redis> GET mykey
“hello”
redis>
使用SETNX实现分布式锁
多个进程执行以下Redis命令:
SETNX lock.foo <current Unix time + lock timeout + 1>
如果 SETNX 返回1,说明该进程获得锁,SETNX将键 lock.foo 的值设置为锁的超时时间(当前时间 + 锁的有效时间)。
如果 SETNX 返回0,说明其他进程已经获得了锁,进程不能进入临界区。进程可以在一个循环中不断地尝试 SETNX 操作,以获得锁。
package net.csdn.redis;import java.util.concurrent.TimeUnit;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;public class RedisDemo {private static JedisPool pool;private static String redisServerIp = "192.168.0.43";private static String redisPassord = "MMHlive2016";private static int connectTimeout = 20 * 1000;// 2秒/** * 建立连接池 真实环境,一般把配置参数缺抽取出来。 * */private static void createJedisPool() {// 建立连接池配置参数JedisPoolConfig config = new JedisPoolConfig();// 设置最大连接数config.setMaxActive(10000);// 设置最大阻塞时间,记住是毫秒数millisecondsconfig.setMaxWait(connectTimeout);// 设置空间连接config.setMaxIdle(500);// 创建连接池pool = new JedisPool(config, redisServerIp, 6379, connectTimeout, redisPassord);}/** * 在多线程环境同步初始化 */private static synchronized void poolInit() {if (pool == null)createJedisPool();}/** * 获取一个jedis 对象 * * @return */private static Jedis getJedis() {if (pool == null)poolInit();return pool.getResource();}/** * 归还一个连接 * * @param jedis */private static void returnRes(Jedis jedis) {pool.returnResource(jedis);}public static long setnx(String key, String val, int timeout) {Jedis jedis = getJedis();long rst = jedis.setnx(key, val);if (rst == 1) {jedis.expire(key, timeout);}returnRes(jedis);return rst;}public static long delete(String sessionId) {Jedis jedis = getJedis();Long rst = jedis.del(sessionId);returnRes(jedis);return rst;}public static boolean tryLock(String key, int timeout) {long nano = System.nanoTime();do { Long i = setnx(key, key, timeout);//System.out.println(i);if (i == 1) {System.out.println(Thread.currentThread().getName()+":获得锁");return true;}if (timeout == 0) {break;}try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}if((System.nanoTime() - nano) > TimeUnit.SECONDS.toNanos(timeout)){break;}} while (true);throw new RuntimeException("获取[" + key + "]锁超时");}public static void main(String[] args) throws Exception {String key="wweerrt";delete(key);int timeout=1000000;new Thread(()->{System.out.println(Thread.currentThread().getName()+":开始加锁");tryLock(key, timeout);}) .start();new Thread(()->{System.out.println(Thread.currentThread().getName()+":开始加锁");tryLock(key, timeout);}) .start();Thread.sleep(100000L);}}
控制台输出:
Thread-1:开始加锁
Thread-2:开始加锁
Thread-1:获得锁
阅读全文
0 0
- redis实战教程(一)-分布式锁
- Redis分布式锁,开发实战
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
- redis教程(一)
- redis 实战系列(一)
- Redis入门实战(一)
- Redis实战总结(一)
- 基于 redis 实现的分布式锁(一)
- Redis实战教程
- RabbitMQ 实战教程(一)
- redis教程(一):redis的安装
- Redis教程(一)- 安装
- apache shiro分布式session共享实战(redis版)
- Redis实战(一) 使用缓存合理性
- Redis实战(一) 使用缓存合理性
- C# Redis实战(一)
- iOS Crash闪退日志的捕获和上传至服务器
- PHP五大新特性
- java序列化与反序列化
- springMvc 的参数验证 BindingResult result 的使用
- angular5项目笔记汇总
- redis实战教程(一)-分布式锁
- LinuxMint解决中文文本乱码问题
- 在window下搭建Vue.Js开发环境
- 《计算机操作系统》总结六(内存管理)
- ANDROID L——Material Design详解(动画篇)
- leetcode---657. Judge Route Circle
- Android.mk入门到精通(003)——Android.mk用法详解
- clearcase 使用手册
- 怎么做静态网页