package redis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; public class RedisLock { public static void main(String[] args) { JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
// 从连接池中获取一个jedis对象
Jedis jedis = jedisPool.getResource(); //简单加redis分布式锁的方式
boolean lock = false;
String key = "mylock";
String value = System.currentTimeMillis()+""; try {
//50秒自动解锁
String setResult = jedis.set(key,value , "nx", "ex", 50L);
long startTime = 0;
if (setResult!=null) {
lock = true;
startTime = System.currentTimeMillis();
} //没有获取到锁,退出
if (!lock) {
return;
} //执行到了这一步说明已经获取到锁
// doSth long endTime = System.currentTimeMillis();
//如果超时解锁
if ((endTime-startTime)>5000) {
//打印日志
System.out.println("出现超时解锁-----------key:"+key);
} } catch (Exception e) {
e.printStackTrace();
}finally {
//这里是为了避免超时后,释放掉其他线程的同名锁
//但是有个问题,就是下面的代码不是原子操作,可能会有问题,这里忽略
String s = jedis.get(key);
if (value.equals(s)) {
//释放锁
jedis.del(key);
}
} }
}
package redis;

import java.util.HashMap;
import java.util.Map; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; public class RedisReentrantLock { private ThreadLocal<Map<String,Integer>> lockers = new ThreadLocal<>();
private Jedis jedis; public RedisReentrantLock(Jedis jedis) {
super();
this.jedis = jedis;
} private boolean _lock(String key) {
return jedis.set(key,"" , "nx", "ex", 5L)!=null;
} private void _unlock(String key) {
jedis.del(key);
} private Map<String, Integer> currentLockers(){
Map<String, Integer> refs = lockers.get();
if (refs !=null) {
return refs;
}
lockers.set(new HashMap<String, Integer>());
return lockers.get();
} public boolean lock(String key) {
Map<String, Integer> refs = currentLockers();
Integer refCnt = refs.get(key);
if (refCnt!=null) {
refs.put(key, refCnt+1);
return true;
}
boolean ok = this._lock(key);
if (!ok) {
return false;
} refs.put(key, 1);
return true;
} public boolean unlock(String key) {
Map<String, Integer> refs = currentLockers();
Integer refCnt = refs.get(key);
if (refCnt == null) {
return false;
}
refCnt -= 1;
if (refCnt>0) {
refs.put(key, refCnt);
}else {
refs.remove(key);
this._unlock(key);
}
return true;
} public static void main(String[] args) {
JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
// 从连接池中获取一个jedis对象
Jedis jedis = jedisPool.getResource();
RedisReentrantLock redisLock = new RedisReentrantLock(jedis);
System.out.println(redisLock.lock("lock1"));
System.out.println(redisLock.lock("lock1"));
System.out.println(redisLock.unlock("lock1"));
System.out.println(redisLock.unlock("lock1"));
} }

redis分布式锁练习【我】的更多相关文章

  1. 利用redis分布式锁的功能来实现定时器的分布式

    文章来源于我的 iteye blog http://ak478288.iteye.com/blog/1898190 以前为部门内部开发过一个定时器程序,这个定时器很简单,就是配置quartz,来实现定 ...

  2. Redis分布式锁

    Redis分布式锁 分布式锁是许多环境中非常有用的原语,其中不同的进程必须以相互排斥的方式与共享资源一起运行. 有许多图书馆和博客文章描述了如何使用Redis实现DLM(分布式锁管理器),但是每个库都 ...

  3. redis分布式锁和消息队列

    最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP ...

  4. redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  5. spring boot redis分布式锁

    随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...

  6. Redis分布式锁的正确实现方式

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  7. Redis分布式锁---完美实现

    这几天在做项目缓存时候,因为是分布式的所以需要加锁,就用到了Redis锁,正好从网上发现两篇非常棒的文章,来和大家分享一下. 第一篇是简单完美的实现,第二篇是用到的Redisson. Redis分布式 ...

  8. redis分布式锁实践

    分布式锁在多实例部署,分布式系统中经常会使用到,这是因为基于jvm的锁无法满足多实例中锁的需求,本篇将讲下redis如何通过Lua脚本实现分布式锁,不同于网上的redission,完全是手动实现的 我 ...

  9. Redis分布式锁的try-with-resources实现

    Redis分布式锁的try-with-resources实现 一.简介 在当今这个时代,单体应用(standalone)已经很少了,java提供的synchronized已经不能满足需求,大家自然 而 ...

  10. 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

随机推荐

  1. prometheus 配置项注意事项

    1.job:metrics_path 如果是静态模式下配置job(statics),直接配置job的metrics_path选项是不生效的.需要同时在exporter端指定metrics_path.如 ...

  2. Linux磁盘管理——swap分区

    转自:Linux Swap交换分区设置 对swap分区的误解 一种流行的.以讹传讹的说法是,安装Linux系统时,交换分区swap的大小应该是内存的两倍.也就是说,如果内存是2G,那么就应该分出4G的 ...

  3. linux 基础9-账号与身份管理

    1. linux的账号与群组 1.1 账户名称:/etc/passwd: head -n 5 /etc/password #取前5行 账号名称,对应UID 密码,早期是在这里,后来转到了/etc/sh ...

  4. HDU 6568 Math

    Math \(f_i\)为从\(i\)到\(i+1\)的期望步数. \(f_i = 1-p + p(f_i + 2((1-q)^{n-i}(n-i) + q\sum_{j=0}^{n-i-1}(1-q ...

  5. Python计算AUC

    AUC(Area under curve)是机器学习常用的二分类评测手段,直接含义是ROC曲线下的面积.另一种解释是:随机抽出一对样本(一个正样本,一个负样本),然后用训练得到的分类器来对这两个样本进 ...

  6. Python 字节码bytecode

    字节码bytecode python把源码文件编译成字节码文件,存放在__pycahe子目录内,用.pyc结尾.之后如果不再修改源码文件,运行时则使用*.pyc文件编译成机器码,这样不但运行速度快,而 ...

  7. React 新特性学习

    1 context 2 contextType 3 lazy 4 suspense 5 memo 6 hooks 7 effect hooks =========== 1 Context 提供了一种方 ...

  8. mybatis-oracle 新增序列

    1.参考 https://blog.csdn.net/qq_29001173/article/details/82106853 2.思考: 2.1获取序列下一个值:seq_car.nextval 2. ...

  9. 简单的JAVAWeb选课系统

    该系统管理员可以添加和删除学生.教师,教师可以修改自己信息.添加课程.浏览自己课程,学生可以修改自己的信息.选课.浏览全部课程. 首先展示文件: 然后就是一次展示代码: Guanli包中代码: pac ...

  10. 下拉框 显示name 隐藏code

    暂未做详细整理, 后期有机会完善 jsp 是否有效: <s:select id="queryIsValid" name="configBean.queryIsVal ...