redis锁
1.引入依赖:
<!--使用redis客户端需要用到的包 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.3</version>
</dependency>
2.连接redis:
package com.karat.cn.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* 客户端连接redis
* @author 开发
*
*/
public class RedisManager {
private static JedisPool jedisPool;
static {
JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);//最大连接数, 默认8个
jedisPoolConfig.setMaxIdle(10);//最小空闲连接数, 默认0
jedisPool=new JedisPool(jedisPoolConfig, "47.107.121.215",6379);
}
public static Jedis getJedis() throws Exception {
if(jedisPool!=null) {
//getResource()方法从连接池中取得一个Jedis实例
return jedisPool.getResource();
}
throw new Exception("jedis启动异常");
}
}
3.锁测试:
package com.karat.cn.redis;
import java.util.List;
import java.util.UUID;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
public class RedisLock {
/**
* 上锁
* @param key 锁key值
* @param timeout 获取请求时间(多长时间获取不到锁表示失败)
* @return
*/
public String getLock(String key,int timeout) {
try {
Jedis jedis=RedisManager.getJedis();//连接获取jedis实列
String value=UUID.randomUUID().toString();//随机设置值UUID(值无所谓)
//连接超时时间,到了该设置时间,锁还没有被释放(没有抢到),结束
long end=System.currentTimeMillis()+timeout;
while(System.currentTimeMillis()<end) {//阻塞
/**
* setnx
* 返回整数,具体为
* 1,当 key 的值被设置
* 0,当 key 的值没被设置
*/
if(jedis.setnx(key, value)==1) {//插入数据成功
//设置key超时时间
jedis.expire(key, timeout);
//锁设置成功,redis操作成功
return value;
}
//获得key的过期时间
if(jedis.ttl(key)==1){
jedis.expire(key, timeout);
}
Thread.sleep(1000);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 释放锁
* @param key
* @param value
* @return
*/
public boolean delLock(String key,String value) {
try {
Jedis jedis=RedisManager.getJedis();//连接获取jedis实列
while(true) {
jedis.watch(key);
//判断获得锁的线程和当前线程redis中存的值一样
if(value.equals(jedis.get(key))) {
Transaction transaction=jedis.multi();//去开启事务
transaction.del(key);//删除key
List<Object> list=transaction.exec();//执行事务
if(list==null) {
continue;
}
return true;
}
jedis.unwatch();
break;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
/**
* 测试
* @param args
*/
public static void main(String args[]) {
RedisLock lock=new RedisLock();
String lookId=lock.getLock("aaa", 10000);
if(null!=lookId) {
System.out.println("获取锁成功");
}
System.out.println("失败");
String mm=lock.getLock("aaa", 10000);
System.out.println(mm);
}
}
redis中有一个setNx命令,这个命令只有在key不存在的情况下为key设置值
redis锁的更多相关文章
- (实例篇)php 使用redis锁限制并发访问类示例
1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制 ...
- php 使用redis锁限制并发访问类
1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制 ...
- 解锁redis锁的正确姿势
解锁redis锁的正确姿势 redis是php的好朋友,在php写业务过程中,有时候会使用到锁的概念,同时只能有一个人可以操作某个行为.这个时候我们就要用到锁.锁的方式有好几种,php不能在内存中用锁 ...
- redis锁处理并发问题
redis锁处理并发问题 redis锁处理高并发问题十分常见,使用的时候常见有几种错误,和对应的解决办法. set方式 setnx方式 setnx+getset方式 set方式 加锁:redis中se ...
- redis 初步认识四(redis锁,防并发)
using System; namespace ConsoleAppRedis { class Program { static void Main(string[] args) { //第一种,无登 ...
- redis锁机制介绍与实例
转自:https://m.jb51.net/article/154421.htm 今天小编就为大家分享一篇关于redis锁机制介绍与实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要 ...
- 定时任务redis锁+自定义lambda优化提取冗余代码
功能介绍: 我系统中需要跑三个定时任务,由于是多节点部署,为了防止多个节点的定时任务重复执行.所以在定时任务执行时加个锁,抢到锁的节点才能执行定时任务,没有抢到锁的节点就不执行.从而避免了定时任务重复 ...
- 多线程并发问题解决之redis锁
一 问题背景 我们做的是医疗信息化系统,在系统中一条患者信息对医院中当前科室中的所有诊断医生是可见的,当有一个诊断医生点击按钮处理该数据时,数据的状态发生了变化,其他的医生就不可以再处理此患者的数据了 ...
- Redis 锁的实现方案
开发中不可避免的是碰到并发请求,在数据严谨性的要求不高时,我们也不需要做什么处理,但如果碰到数据严谨性非常高的时候(例如:用户金额,秒杀产品的库存...),我们就需要慎重处理了. 解决方案多种多样,下 ...
- PHP Redis锁
一.什么是 Redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库 二.什么是 Redis 分布式锁 分布式锁其实可以理解为:控 ...
随机推荐
- codeforce 462DIV2 C题
题意 给出一个只含有1和2的序列,有n个元素,可以选择一段区间进行翻转操作,求再反转后的最大非递减子序列的长度 分析 太菜了只想出了N^2的做法.序列只有1和2,那么每个非递减子序列都会有一个分界点, ...
- rsync 服务器架设方法
作者: 北南南北 来自:Linuxsir.Org 摘要: rsync 是一个快速增量文件传输工具,它可以用于在同一主机备份内部的备分,我们还可以把它作为不同主机网络备份工具之用.本文主要讲述的是如何自 ...
- laravel 验证表单信息
1控制器验证 $this->validate($request,[ 'Student.name'=>'required|min:2|max:20', 'Student.age'=>' ...
- 19-字符串匹配(kmp || substr,find)
链接:https://www.nowcoder.com/acm/contest/77/C来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 利用HttpWebRequest类Post数据至URI
在与第三方系统进行数据对接时,需要把数据post到对方提供的一个url,然后进行相关处理. 这里可利用HttpWebRequest类,该类位于System.Net命名空间下.它提供了一些属性和方法可以 ...
- tensor 维度 问题。
tf.argmax takes two arguments: input and dimension. example: tf.argmx(arr, dimension = 1). or tf.arg ...
- Python基础入门-IF语句
今天给大家分享一下Python中的IF语句的使用场景以及注意事项.主要内容如下: 1.python中的真假 2.Python操作符 3.if语句实例和嵌套实例 4.if语句中的if嵌套实例 5.and ...
- 【Head First Java 读书笔记】(六)认识Java API
第五章 使用Java函数库 ArrayList add(Object elem) remove(int index) remove(Object elem) contains(Object elem) ...
- C#中ref和out的作用和区别
相同点:方法的定义和调用都必须显示使用ref.out关键字.都会导致参数按引用传递. 不同点:传递给ref关键字的参数必须赋初始值,而out不用.out关键字会清空变量,即使变量已经赋值也不行,退出函 ...
- spring的一些配置和重要的接口和类
spring的配置文件 通常是applicationContext.xml(具体的bean配置会在后面内容中详解) setter方法注入: <property name=“” value=“ja ...