博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分布式锁 基于Redis
阅读量:6184 次
发布时间:2019-06-21

本文共 3998 字,大约阅读时间需要 13 分钟。

参考:http://www.jb51.net/article/75439.htm 

        http://www.linuxidc.com/Linux/2015-01/111827.htm 

        http://www.tuicool.com/articles/6juqmm7 

 方式一: 基于第三方类库 redssion 

1.安装redis

安装redssion的锁服务队redis的版本有要求,要求必须高于2.6版本。关于redis的安装,请参考。

2.redssion库

redssion的库添加的pom文件中去。

   
org.redisson
   
redisson
   
2.1.0

3.测试例子

Config config = new Config();         config.useSingleServer().setAddress("ipaddress:6379");         Redisson redisson = Redisson.create(config);                  for(int i=0;i<5;i++){
        RLock lock = redisson.getLock("testLock");         lock.lock(10, TimeUnit.SECONDS);//10s超时         logger.info("the lock client id is client{}",i);         Thread.sleep(1000);         logger.info("client{} unlock",i);         lock.unlock();         }

4.参考

 

 

方式二: 自定义代码实现 

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; /**  * redis实现的分布式锁  */ public final class Lock {
private static final String LOCK = "redis:lock:%s"; private static final int EXPIRE = 20 * 60;//20分钟 private static final Logger logger = LoggerFactory.getLogger(Lock.class); private Lock() {
} public static Lock getLock() {
return new Lock(); } /** * 获得锁,超时退出 * @param id * @param timeout 超时时间(ms) * @return */ public boolean lock(String id, int timeout) {
//这里的Jedis实际上是个代理。代理类JedisCallback,JedisFactoryBean Jedis jedisProxy = JedisProxy.create(); long lock = 0; long start = System.currentTimeMillis(); while (lock != 1) {
long now = System.currentTimeMillis(); //判断超时 if (timeout > 0 && now > start + timeout) {
return false; } long timestamp = now + EXPIRE * 1000 + 1; try {
String key = String.format(LOCK, id); lock = jedisProxy.setnx(key, String.valueOf(timestamp)); if (lock == 1) {
logger.info("设置redis锁key成功,lock key=" + key); jedisProxy.expire(key, EXPIRE); logger.info("设置redis锁key过期时间成功,lock key=" + key); } else {
String s = jedisProxy.get(key); Long lastLockTime = Long.parseLong(s); //一个项目部署多个服务,锁可能已经被相同定时任务的其他进程获得,则直接返回false if (jedisProxy.ttl(key)!=-1&&lastLockTime > System.currentTimeMillis()){
logger.info("redis锁已经被其他服务获得,lock key=" + key); return false; } /** * 如果上次锁定的时间已经过期,则清除key锁,以便定时任务能够启动 * 造成未能释放的原因主要是jedis.expire(key, EXPIRE);失败 * 或者是获取锁之后,由于程序错误或网络错误,unlock未被成功调用 */ if (jedisProxy.ttl(key)==-1||lastLockTime < System.currentTimeMillis()) {
jedisProxy.del(key); continue; } // this.wait(100); Thread.sleep(100); } } catch (Exception e) {
logger.error("从redis获取定时任务锁错误,key="+String.format(LOCK, id), e); return false; } } return true; } /** * 释放锁 * @param id */ public void unLock(String id) {
//这里的Jedis实际上是个代理。代理类JedisCallback,JedisFactoryBean Jedis jedisProxy = JedisProxy.create(); String key = String.format(LOCK, id); jedisProxy.del(key); } }

JedisProxy类

/**  * Jedis代理  */ @Component public class JedisProxy implements ApplicationContextAware {
private static volatile ApplicationContext ac; /** * 创建Jedis 代理 * * @return */ public static Jedis create() {
return ac.getBean(Jedis.class); } @Override public void setApplicationContext(ApplicationContext applicationContext) {
if (ac != null) {
return; } synchronized (JedisProxy.class) {
if (ac != null) {
return; } ac = applicationContext; } } }

 

 

 

 

 

 

转载地址:http://obsda.baihongyu.com/

你可能感兴趣的文章
个人工作年终总结
查看>>
【CentOS 7LAMP架构5】,使用php与apache结合#171220
查看>>
挂载失误造成的启动失败
查看>>
我的友情链接
查看>>
GEC粤嵌开发板介绍
查看>>
Java递归遍历文件夹
查看>>
用syncios导出iphone中的文件
查看>>
不是办法的办法,关于docker错误
查看>>
Percona XtraDB Cluster 5.6安装配置
查看>>
RGW Cache类解析
查看>>
Linux tar 加密解密
查看>>
【springMVC基础】spring获取bean的几种方法
查看>>
Hadoop学习笔记14:./bin/hadoop namenode -format之源码解析
查看>>
SSH两种登陆认证剖析(搜狗面试)
查看>>
解决SyntaxError: invalid syntax
查看>>
创建android程序会出现两个布局文件
查看>>
从plist文件中读取数据
查看>>
MySQL 5.7中添加用户,新建数据库,用户授权,删除用户,修改密码
查看>>
配置rstatd使用LoadRunner监控Linux系统资源
查看>>
python 基于Digngo 开发web程序和处理get、post请求
查看>>