借助共享缓存redis实现分布式互斥锁

新开发的系统需要控制每个时刻回收缓存的GC线程有且只有一个在运行,如果有多个线程同时运行,会造成系统崩溃。如果只有一个JVM进程那么很好办,简单的借助synchronized关键字就行了。可是我的系统要部署在多台服务器,每台服务器上部署多个实例上。而synchronized仅仅在单进程里有用。

考虑借助共享数据源redis实现功能。

redis提供一个方法,SETNX key value。将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。设置成功,返回 1 。设置失败,返回 0 。

那么这个key就是一把锁,如果返回1,表示获取互斥锁成功,然后可以进入临界区。返回0,表示获取失败,无法进入临界区。

示例代码:

		try {
			mutex = KeyHelper.Data.Risk.getGcThreadMutexKey();
			if (dataCommonCacheService.setnx(mutex, "ok") == 1L) { // 尝试加锁
				garbageCollector.garbageRecycle(); // 临界区
			}
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		} finally {
			dataCommonCacheService.del(mutex);	// 释放锁
		}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-18 20:50:20

借助共享缓存redis实现分布式互斥锁的相关文章

基于(Redis | Memcache)实现分布式互斥锁

设计一个缓存系统,不得不要考虑的问题就是:缓存穿透.缓存击穿与失效时的雪崩效应. 缓存击穿 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义.在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞. 解决方案 有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap

剖析curator的分布式互斥锁原理

1 前言 最近在做项目的时候,遇到一个多线程访问申请一个资源的问题.需要每个线程都能够最终在有效的时间内申请到或者超时失败.以前一般这种方式用的是redis做枷锁机制,每个线程都去redis加一把共同的锁,如果枷锁成功,则执行资源申请操作.而没有枷锁成功的线程,则在有效时间内循环尝试去枷锁,并且每次木有加锁成功,则就Thread.sleep()一会. 通过这种方式可以看出,这里对于sleep的时间间隔要求设置很严格,如果太小,则就会增加大规模的redis请求操作:而如果太长,当资源可用的时候,但

【redis】基于redis实现分布式并发锁

基于redis实现分布式并发锁(注解实现) 说明 前提, 应用服务是分布式或多服务, 而这些"多"有共同的"redis"; GitHub: https://github.com/vergilyn/SpringBootDemo 代码结构: 一.分布式并发锁的几种可行方案 (具体实现思路参考: 分布式锁的实现.如何用消息系统避免分布式事务?) 1.基于数据库 可以用数据库的行锁for update, 或专门新建一张锁控制表来实现. 过于依赖数据库, 且健壮性也不是特别好

基于Zookeeper实现的分布式互斥锁 - InterProcessMutex

Curator是ZooKeeper的一个客户端框架,其中封装了分布式互斥锁的实现,最为常用的是InterProcessMutex,本文将对其进行代码剖析 简介 InterProcessMutex基于Zookeeper实现了分布式的公平可重入互斥锁,类似于单个JVM进程内的ReentrantLock(fair=true) 构造函数 1234567891011121314151617 // 最常用public InterProcessMutex(CuratorFramework client, St

使用Redis的分布式Java锁

通过优锐课的java学习分享中,了解有关分布式锁定以及如何在项目中实现它的更多信息! 什么是分布式锁定? 在多线程程序中,不同的线程可能需要访问相同的资源.但是,允许所有线程同时访问资源可能导致争用情况,错误和其他意外行为. 为了确保没有两个线程可以同时访问同一资源,并确保以可预测的顺序对资源进行操作,程序员使用一种称为锁的机制.每个线程首先获取锁,然后对资源进行操作,最后将锁释放给其他线程. 在Java中,由于多种原因,锁定对象通常比使用同步块更灵活.首先,Lock API可以以不同的方法运行

Linux系统编程——线程同步与互斥:互斥锁

为什么需要互斥锁? 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源.这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西,如果不做任何处理的话,打印出来的东西肯定是错乱的. 下面我们用程序模拟一下这个过程,线程一需要打印" hello ",线程二需要打印" world ",不加任何处理的话,打印出来的内容会错乱: #include <stdio.h> #include <

信号量、互斥锁、自旋锁

信号量: 是用来解决进程/线程之间的同步和互斥问题的一种通信机制,是用来保证两个或多个关键代码不被并发调用. 信号量(Saphore)由一个值和一个指针组成,指针指向等待该信号量的进程.信号量的值表示相应资源的使用情况.信号量S>=0时,S表示可用资源的数量.执行一次P操作意味着请求分配一个资源,因此S的值减1:当S<0时,表示已经没有可用资源,S的绝对值表示当前等待该资源的进程数.请求者必须等待其他进程释放该类资源,才能继续运行.而执行一个V操作意味着释放一个资源,因此S的值加1:若S<

Linux多线程编程-互斥锁

互斥锁 多线程编程中,(多线程编程)可以用互斥锁(也称互斥量)可以用来保护关键代码段,以确保其独占式的访问,这有点像二进制信号量.POSIX互斥锁相关函数主要有以下5个: #include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_destroy(pthread_mutex_t *mutex); int p

互斥锁概念简单说明和举例

本文内容主要来自博文:Linux系统编程--线程同步与互斥:互斥锁 同时补充以下博文说明: [1]  Linux线程-互斥锁pthread_mutex_t [2]  POSIX 互斥锁: pthread_mutex_t 为什么需要互斥锁? 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源.这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西,如果不做任何处理的话,打印出来的东西肯定是错乱的. 下面我们用程序模拟一下这个过