转自:https://m.jb51.net/article/154421.htm

今天小编就为大家分享一篇关于redis锁机制介绍与实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

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锁机制介绍与实例的更多相关文章

  1. Mysql锁机制介绍

    Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  2. Redis高级特性介绍及实例分析

    转自:http://www.jianshu.com/p/af7043e6c8f9   Redis基础类型回顾 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的St ...

  3. Redis高级特性介绍以及实例分析

    Redis基础类型回顾 转自:http://www.jianshu.com/p/af7043e6c8f9 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的Stri ...

  4. JAVA记录-redis缓存机制介绍(四)

    Redis 数据备份与恢复 Redis SAVE 命令用于创建当前数据库的备份. 语法 redis Save 命令基本语法如下: redis 127.0.0.1:6379> SAVE 实例 re ...

  5. JAVA记录-redis缓存机制介绍(一)

    1.redis介绍 Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Re ...

  6. JAVA记录-redis缓存机制介绍(三)

    Redis 事务 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的 ...

  7. JAVA记录-redis缓存机制介绍(二)

    Redis 集合(Set) Redis的Set是string类型的无序集合.集合成员是唯一的,这就意味着集合中不能出现重复的数据. Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度 ...

  8. php实现redis锁机制

    <?php class Redis_lock { public static function getRedis() { $redis = new redis(); $redis->con ...

  9. Redis锁机制的几种实现方式

    1. redis加锁分类 redis能用的的加锁命令分表是INCR.SETNX.SET 2. 第一种锁命令INCR 这种加锁的思路是, key 不存在,那么 key 的值会先被初始化为 0 ,然后再执 ...

随机推荐

  1. JDK11&12 新特性学习

  2. HTML5中的语义标签兼容IE8以及更低版本的浏览器

    看某教程,说让HTML5的这些语义标签能够兼容低版本的浏览器,原文是“你可以设置css的display属性为block”.很好理解,就设置css样式为block嘛,那就直接设置咯: header, s ...

  3. html 出现粒子线条,鼠标移动会以鼠标为中心吸附的特效之canvas-nest.js插件

    我在网上看到一个很炫酷,很有趣的特效,网页上会有很多移动的粒子和线条,鼠标经过时会以鼠标为中心吸附过来,如果时间够久,会形成一个类似震动的.带辐条的车轮子的东西. 网上搜了一下,源码是github里面 ...

  4. 【SQL触发器】类型 FOR 、AFTER、 Instead of

    1.AFTER(for)触发器 (操作后) after触发器是指在操作成功后,所采取的一些动作! 比如:下面是我创建好的一个after触发器 creat trigger [dbo].[T_Carego ...

  5. Spark分布式编程之全局变量专题【共享变量】

    转载自:http://www.aboutyun.com/thread-19652-1-1.html 问题导读 1.spark共享变量的作用是什么?2.什么情况下使用共享变量?3.如何在程序中使用共享变 ...

  6. 【转】Syncthing – 数据同步利器---自己的网盘,详细安装配置指南,内网使用,发现服务器配置

    Syncthing – 数据同步利器---自己的网盘,详细安装配置指南,内网使用,发现服务器配置 原贴:https://www.cnblogs.com/jackadam/p/8568833.html ...

  7. mysql合并表

    有如下两张表 a +------+------+---------+ | uid | name | addtime | +------+------+---------+ | | | +------+ ...

  8. HTML 块级元素 行内元素

    块级元素 - block level element 总是在新行上开始: 高度,行高以及外边距和内边距都可控制: 宽度缺省是它的容器的100%,除非设定一个宽度: 它可以容纳内联元素和其他块元素 如: ...

  9. 转 Ubuntu16.04+QT4.8.7开发环境搭建

    Qt安装步骤1.安装g++以及依赖库 sudo apt-get install g++  sudo apt-get install g++-multilib libx11-dev libxext-de ...

  10. @Async异步注解与SpringBoot结合使用

    当你在service层需要启动异步线程去执行某些分支任务,又不希望显式使用Thread等线程相关类,只想专注于实现业务逻辑代码开发,可以使用@Async异步注解. 1. 使用@Async 异步注解 C ...