redis锁机制介绍与实例
转自:https://m.jb51.net/article/154421.htm
1 悲观锁
执行操作前假设当前的操作肯定(或有很大几率)会被打断(悲观)。基于这个假设,我们在做操作前就会把相关资源锁定,不允许自己执行期间有其他操作干扰。
Redis不支持悲观锁。Redis作为缓存服务器使用时,以读操作为主,很少写操作,相应的操作被打断的几率较少。不采用悲观锁是为了防止降低性能。
2 乐观锁
执行操作前假设当前操作不会被打断(乐观)。基于这个假设,我们在做操作前不会锁定资源,万一发生了其他操作的干扰,那么本次操作将被放弃。
3. Redis中的锁策略
Redis采用了乐观锁策略(通过watch操作)。乐观锁支持读操作,适用于多读少写的情况!
在事务中,可以通过watch命令来加锁;使用 UNWATCH可以取消加锁;
如果在事务之前,执行了WATCH(加锁),那么执行EXEC 命令或 DISCARD 命令后,锁对自动释放,即不需要再执行 UNWATCH 了
例子
redis锁工具类
package com.fly.lock;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisLock {
//初始化redis池
private static JedisPoolConfig config;
private static JedisPool pool;
static {
config = new JedisPoolConfig();
config.setMaxTotal(30);
config.setMaxIdle(10);
pool = new JedisPool(config, "192.168.233.200", 6379);
}
/**
* 给target上锁
* @param target
**/
public static void lock(Object target) {
//获取jedis
Jedis jedis = pool.getResource();
//result接收setnx的返回值,初始值为0
Long result= 0L;
while (result < 1) {
//如果target在redis中已经存在,则返回0;否则,在redis中设置target键值对,并返回1
result = jedis.setnx(target.getClass().getName() + target.hashCode(), Thread.currentThread().getName());
}
jedis.close();
}
/**
* 给target解锁
* @param target
**/
public static void unLock(Object target) {
Jedis jedis = pool.getResource();
//删除redis中target对象的键值对
Long del = jedis.del(target.getClass().getName() + target.hashCode());
jedis.close();
}
/**
* 尝试给target上锁,如果锁成功返回true,如果锁失败返回false
* @param target
* @return
**/
public static boolean tryLock(Object target) {
Jedis jedis = pool.getResource();
Long row = jedis.setnx(target.getClass().getName() + target.hashCode(), "true");
jedis.close();
if (row > 0) {
return true;
}
return false;
}
}
测试类
package com.fly.test;
import com.fly.lock.RedisLock;
class Task {
public void doTask() {
//上锁
RedisLock.lock(this);
System.out.println("当前线程: " + Thread.currentThread().getName());
System.out.println("开始执行: " + this.hashCode());
try {
System.out.println("doing...");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成: " + this.hashCode());
//解锁
RedisLock.unLock(this);
}
}
public class Demo {
public static void main(String[] args) {
Task task = new Task();
Thread[] threads = new Thread[5];
for (Thread thread : threads) {
thread = new Thread(()->{
task.doTask();
});
thread.start();
}
}
}
输出结果:
----------------------------------------------
当前线程: Thread-0
开始执行: 2081499965
doing...
完成: 2081499965
----------------------------------------------
当前线程: Thread-2
开始执行: 2081499965
doing...
完成: 2081499965
----------------------------------------------
当前线程: Thread-1
开始执行: 2081499965
doing...
完成: 2081499965
----------------------------------------------
当前线程: Thread-4
开始执行: 2081499965
doing...
完成: 2081499965
----------------------------------------------
当前线程: Thread-3
开始执行: 2081499965
doing...
完成: 2081499965
去掉redis锁后,执行结果:
----------------------------------------------
----------------------------------------------
当前线程: Thread-2
开始执行: 1926683415
----------------------------------------------
当前线程: Thread-1
doing...
当前线程: Thread-0
----------------------------------------------
当前线程: Thread-3
开始执行: 1926683415
doing...
开始执行: 1926683415
doing...
----------------------------------------------
开始执行: 1926683415
doing...
当前线程: Thread-4
开始执行: 1926683415
doing...
完成: 1926683415
完成: 1926683415
完成: 1926683415
完成: 1926683415
完成: 1926683415
Process finished with exit code 0
利用redis这个性质,可以实现分布式锁,当然设计一定复杂一些!
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接
redis锁机制介绍与实例的更多相关文章
- Mysql锁机制介绍
Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...
- Redis高级特性介绍及实例分析
转自:http://www.jianshu.com/p/af7043e6c8f9 Redis基础类型回顾 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的St ...
- Redis高级特性介绍以及实例分析
Redis基础类型回顾 转自:http://www.jianshu.com/p/af7043e6c8f9 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的Stri ...
- JAVA记录-redis缓存机制介绍(四)
Redis 数据备份与恢复 Redis SAVE 命令用于创建当前数据库的备份. 语法 redis Save 命令基本语法如下: redis 127.0.0.1:6379> SAVE 实例 re ...
- JAVA记录-redis缓存机制介绍(一)
1.redis介绍 Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Re ...
- JAVA记录-redis缓存机制介绍(三)
Redis 事务 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...
- JAVA记录-redis缓存机制介绍(二)
Redis 集合(Set) Redis的Set是string类型的无序集合.集合成员是唯一的,这就意味着集合中不能出现重复的数据. Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度 ...
- php实现redis锁机制
<?php class Redis_lock { public static function getRedis() { $redis = new redis(); $redis->con ...
- Redis锁机制的几种实现方式
1. redis加锁分类 redis能用的的加锁命令分表是INCR.SETNX.SET 2. 第一种锁命令INCR 这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执 ...
随机推荐
- 恢复win7快捷方式小箭头
reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons&q ...
- 【分布式锁】redis实现
转载:https://www.jianshu.com/p/c970cc710SETNX命令简介 SETNX key value 将key的值设为value,并且仅当key不存在. 若给定的key已经存 ...
- 西门子S7-300 PLC视频教程(百度网盘)
西门子S7-300 PLC视频教程(百度网盘) 百度网盘链接地址: 链接:https://pan.baidu.com/s/1MqC0DJbv-ndCzk9XGU2AYQ 提取码:u5eq 祝大家天天开 ...
- 【转】百度UEditor控件中的map组件不支持https使用的问题解决
原文地址:https://blog.csdn.net/stacy06/article/details/82626363 最近项目部署到了https环境下,使用的UEditor富文本编辑器中的map组件 ...
- nginx配置备份
server { listen 80; server_name localhost; set $expires_duration "30d"; if ($uri ~* \.html ...
- bat文件与Vbs文件常用操作(获取用户输入,执行VBS文件)
bat文件: set /P StrInput="输入数字:" echo 输入的数字为%StrInput% set /P Flg="是否执行(y/n):" IF ...
- vs2010直接调用av_register_all crash问题
需要做一个视频导出的功能,通过ffmpeg来实现,vs2010里面引用ffmpeg库的 dll 和 lib 文件 第一步av_register_all就直接crash了, 查了近半天的时间,都快崩溃了 ...
- bzoj5108: [CodePlus2017]可做题
Description qmqmqm希望给sublinekelzrip出一道可做题.于是他想到了这么一道题目:给一个长度为n的非负整数序列ai,你需 要计算其异或前缀和bi,满足条件b1=a1,bi= ...
- tensorflow学习001——MNIST
1.MNIST是一个入门级的计算机视觉数据集,它包含各种手写数字图片 数据集被分成两部分:60000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test). 这样的 ...
- java常见报错及解决
Java常见报错信息: Java 常见异常种类 Java Exception: 1.Error 2.Runtime Exception 运行时异常 3.Exception 4.throw 用户自定 ...