分布式锁实现二. memcached分布式锁

news2024/11/15 8:33:28

文章目录

  • memcached分布式锁
    • 实现原理:
    • 优缺点
  • 开发准备
    • 安装memcached服务端
    • 安装jar到maven本地仓库
  • 代码开发
    • 初始化Memcached客户端
    • 锁相关操作核心代码
    • 本地运行效果
    • docker运行效果

memcached分布式锁

实现原理:

memcached带有add函数,利用add函数的特性即可实现分布式锁。

add和set的区别在于:如果多线程并发set,则每个set都会成功,但最后存储的值以最后的set的线程为准。而add的话则相反,add会添加第一个到达的值,并返回true,后续的添加则都会返回false。

利用该点即可很轻松地实现分布式锁。

优缺点

优点:并发高效。

缺点:

(1)memcached采用列入LRU置换策略,所以如果内存不够,可能导致缓存中的锁信息丢失。

(2)memcached无法持久化,一旦重启,将导致信息丢失。

开发准备

安装memcached服务端

在这里插入图片描述
为方便起见,已经将memcached服务器端程序上传到下面的目录,使用时只需要双击运行就好!
在这里插入图片描述

安装jar到maven本地仓库

开发的时候有的同学可能会遇到下面jar无法下载的情况


		<!-- mvn install:install-file -Dfile="java_memcached-release_2.6.6.jar" -DgroupId=com.danga -DartifactId=java-memcached -Dversion="2.6.6" -Dpackaging=jar -->
		<dependency>
			<groupId>com.danga</groupId>
			<artifactId>java-memcached</artifactId>
			<version>2.6.6</version>
		</dependency>

在java-memcached-2.6.6.jar同级目录运行

mvn install:install-file -Dfile="java_memcached-release_2.6.6.jar" -DgroupId=com.danga -DartifactId=java-memcached -Dversion="2.6.6" -Dpackaging=jar

代码开发

初始化Memcached客户端

@Component
public class MemcachedLockClient
{
    @Value("${memcached.serverUrl:127.0.0.1:11211}")
    private String server;
    
    /**
     * 构建缓存客户端
     */
    private MemCachedClient cachedClient;
    
    @PostConstruct
    public void init()
    {
        cachedClient = new MemCachedClient();
        // 获取连接池实例
        SockIOPool pool = SockIOPool.getInstance();
        // 设置缓存服务器地址,可以设置多个实现分布式缓存
        pool.setServers(new String[] {server});
        // 设置初始连接5
        pool.setInitConn(5);
        // 设置最小连接5
        pool.setMinConn(5);
        // 设置最大连接250
        pool.setMaxConn(250);
        // 设置每个连接最大空闲时间3个小时
        pool.setMaxIdle(1000 * 60 * 60 * 3);
        // 设置连接池维护线程的睡眠时间
        // 设置为0,维护线程不启动
        // 维护线程主要通过log输出socket的运行状况,监测连接数目及空闲等待时间等参数以控制连接创建和关闭。
        pool.setMaintSleep(30);
        // 设置是否使用Nagle算法,因为我们的通讯数据量通常都比较大(相对TCP控制数据)而且要求响应及时,因此该值需要设置为false(默认是true)
        pool.setNagle(false);
        // 设置socket的读取等待超时值
        pool.setSocketTO(3000);
        // 设置socket的连接等待超时值
        pool.setSocketConnectTO(0);
        // 设置完pool参数后最后调用该方法,启动pool。
        pool.initialize();
    }
    
    public void add(String key, Object value)
    {
        cachedClient.set(key, value);
    }
    
    public boolean add(String key, Object value, int milliseconds)
    {
        return cachedClient.add(key, value, milliseconds);
    }
    
    public boolean add(String key, Object value, Date milliseconds)
    {
        return cachedClient.add(key, value, milliseconds);
    }
    
    public void remove(String key)
    {
        cachedClient.delete(key);
    }
    
    public Object get(String key)
    {
        return cachedClient.get(key);
    }
}

锁相关操作核心代码


            String value = RandomStringUtils.randomNumeric(8);
            if (memcachedLock.add("key", value, new Date(System.currentTimeMillis() + 30 * 1000)) == false)
            {
                log.info("报名或抢购失败,请稍后再试! 锁持有者:{}", memcachedLock.get("key"));
                return;
            }
            
            StopWatch clock = new StopWatch();
            try
            {
                // 领取成功
                log.info("★★★★★★★★ {} 报名或抢购处理中★★★★★★★★", memcachedLock.get("key"));
                clock.start();
                // 模拟耗时业务操作
                TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(10000, 20000));
                clock.stop();
                log.info("{} 运行 {} ms ---------------", memcachedLock.get("key"), clock.getLastTaskTimeMillis());
            }
            finally
            {
                memcachedLock.remove("key");
                log.info("释放memcachedLock锁");
            }
        

本地运行效果

在这里插入图片描述

docker运行效果

docker运行方式同 分布式锁实现一
在这里插入图片描述
在这里插入图片描述

有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/964164.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【半监督医学图像分割】2022-MedIA-UWI

【半监督医学图像分割】2022-MedIA-UWI 论文题目&#xff1a;Semi-supervise d me dical image segmentation via a triple d-uncertainty guided mean teacher model with contrastive learning 中文题目&#xff1a;基于对比学习的三维不确定性指导平均教师模型的半监督图像分…

Linux编程--进程--fork使用,创建父子进程

1.使用fork函数创建一个进程 #include <unistd.h>pid_t fork(void); 返回值为0&#xff0c;代表当前进程是子进程 返回值为非负数&#xff0c;代表当前进程为父进程 调用失败&#xff0c;返回-1 代码&#xff1a; #include <stdio.h> #include <sys/types.h&g…

锁( ReentrantLock,Synchronized)

1.lock和synchronized 语法层面 synchronized 是关键字&#xff0c;源码在 jvm 中&#xff0c;用 c 语言实现&#xff1b; Lock 是接口&#xff0c;源码由 jdk 提供&#xff0c;用 java 语言实现&#xff1b; 使用 synchronized 时&#xff0c;退出同步代码块锁会自动释放&…

idea中设置指定图片为项目站标

前提是准备好一张图片 在idea中创建imgs文件夹&#xff0c;放入图片 创建一个HTML文件 建立链接link标签&#xff0c;链接照片即可 <link href"../02css/imgs/2.jpg" rel"shortcut icon" type"image/x-icon"> 执行效果如下图所示&…

音频——I2S 左对齐模式(三)

I2S 基本概念飞利浦(I2S)标准模式左(MSB)对齐标准模式右(LSB)对齐标准模式DSP 模式TDM 模式 文章目录 I2S left波形图逻辑分析仪抓包 I2S left I2S 左对齐标准 标准左对齐格式的数据的 MSB 没有相对于 BCLK 延迟一个时钟。左对齐格式的左右声道数据的 MSB 在 LRCLK 边沿变化后…

斐波那契数【动态规划】

斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n >…

Golang:微服务常用代码分层结构

1.代码结构 代码分层结构是一个老生常谈的话题&#xff0c;好的代码结构能够使得系统易于理解、开发及维护&#xff0c;如果代码结构很混乱就会使得不同层级的代码块耦合&#xff0c;导致难以维护和拓展。 比较经典的代码结构&#xff08;宏观&#xff09;有Web的MVC模式分层结…

SpringBoot整合websockt实现消息对话

文章目录 前言websockt什么是websockt&#xff1f;websockt和Socket区别代码部分实战应用 前言 websockt 什么是websockt&#xff1f; WebSocket是一种在Web应用程序中实现实时双向通信的技术。Web应用程序通常是基于HTTP协议的&#xff0c;HTTP是一种请求/响应式的协议&…

【服务器使用基础】---华为云云耀云服务器实例使用实践

&#x1f996;我是Sam9029&#xff0c;一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **&#x1f431;‍&#x1f409;&#x1f431;‍&#x1f409;恭喜你&#xff0c;若此文你认为写的不错&#xff0c;不要吝啬你的赞扬&#xff0c;求…

肖sir__linux详解__003(vim命令)

linux 文本编辑命令 作用&#xff1a;用于编辑一个文件 用法&#xff1a;vim 文件名称 或者vi &#xff08;1&#xff09;编辑一个存在的文档 例子&#xff1a;编辑一个file1文件 vim aa &#xff08;2&#xff09;编辑一个文件不存在&#xff0c;会先创建文件&#xff0c;再…

Python-图像拼接神器-stitching

多幅图像的拼接 采用这个包&#xff0c;图像拼接结果很好~ 代码只需要三四行 import stitching import cv2imgs ["data/test02/1Hill.jpg","data/test02/2Hill.jpg","data/test02/3Hill.jpg",] stitcher stitching.Stitcher() panorma stit…

postgresql-多表连接

postgresql-多表连接 内连接查询左外连接查询右外连接查询全外连接查询交叉连接查询简写 总结 内连接查询 内连接用于返回两个表中匹配的数据行&#xff0c;使用关键字INNER JOIN表示&#xff0c;也可以简写成JOIN&#xff1b; selecte.first_name ,d.department_id fromcps…

无涯教程-JavaScript - POISSON函数

POISSON函数取代了Excel 2010中的POISSON.DIST函数。 描述 该函数返回泊松分布。泊松分布的常见应用是预测特定时间的事件数。 语法 POISSON(x,mean,cumulative)争论 Argument描述Required/OptionalXThe number of events.RequiredMeanThe expected numeric value.Require…

leecode学习(1)

一、题目 给定一个数组nums和一个目标值target,请你再该数组中找出和为目标值的那两个数&#xff0c;并返回数组的下标&#xff0c;你可以假设输入只会对应一个答案&#xff0c;但是数组的同一个元素不能使用两次。 二、解题思路 目的就是要求出两数之和等于目标值嘛。 就是…

探索树堆Treap和红黑树的优势和劣势

探索树堆Treap和红黑树的优势和劣势 一、背景知识二、树堆&#xff08;Treap&#xff09;的介绍三、红黑树&#xff08;RB-Tree&#xff09;的介绍四、树堆&#xff08;Treap&#xff09;与红黑树&#xff08;RB-Tree&#xff09;的比较总结 博主简介 &#x1f4a1;一个热爱分享…

王道考研数据结构

文章目录 C 环境准备官方文档环境准备在线运行VSCode 环境报错解决 绪论线性表顺序表链表错题 栈、队列和数组栈队列栈的应用之中缀转后缀特殊矩阵用数组压缩存储错题 串模式匹配之暴力和KMP 树与二叉树二叉树树和森林哈夫曼树和哈夫曼编码并查集错题 图图的基本概念图的存储及…

LeetCode494. 目标和

494. 目标和 文章目录 [494. 目标和](https://leetcode.cn/problems/target-sum/)一、题目二、题解方法一&#xff1a;目标和路径计数算法方法二&#xff1a;01背包方法三&#xff1a;01背包一维数组 一、题目 给你一个非负整数数组 nums 和一个整数 target 。 向数组中的每个…

IPC进程间通信及示例代码

一. 什么是进程通信 进程通信&#xff08; InterProcess Communication&#xff0c;IPC&#xff09;就是指进程之间的信息交换。实际上&#xff0c;进程的同步与互斥本质上也是一种进程通信&#xff08;这也就是待会我们会在进程通信机制中看见信号量和 PV 操作的原因了&#x…

Ubuntu18.04使用Systemback制作系统镜像并还原

系列文章目录 文章目录 系列文章目录前言一、下载Systemback工具二、制作系统镜像到U盘三、安装制作系统 前言 在Ubuntu系统中开发项目时&#xff0c;有时会希望将项目移植到另外一台计算机&#xff08;如工控机等&#xff09;上进行部署&#xff0c;通常会在新计算机中安装Ub…

Qt +VTK+Cmake 编译和环境配置(第二篇,中级篇, 重新编译)

1.下载VTK和Cmake 这里不介绍了。我的VTK 8.2.0 cmake 3.27.4 就是不服这编译器了。重新来一次 打开Cmake&#xff0c;把VTK源文件路径和目标路径设置一下&#xff08;目标路径自己设置&#xff0c;随意&#xff09; 点击Configure&#xff1a;。 点击下一步 选择好 Qt的gcc…