在分布式缓存的应用中,会遇到多个客户端同时争用的问题。这个时候,需要用到分布式锁,得到锁的客户端才有操作权限

下面通过一个简单例子介绍:
这里引用的是Memcached.ClientLibrary.dll
//引用
using Memcached.ClientLibrary;
namespace Memcache.AddLock
{
public class MemcacheHelper
{
//实例化Client
public MemcachedClient MClient; public MemcacheHelper()
{
//参数设置
string SockIOPoolName = "demo";
string[] MemcacheServiceList = { "127.0.0.1:11211" }; //设置连接池
SockIOPool SPool = SockIOPool.GetInstance(SockIOPoolName);
SPool.SetServers(MemcacheServiceList);
SPool.Initialize(); MClient = new MemcachedClient();
MClient.PoolName = SockIOPoolName;
//是否启用压缩数据:如果启用了压缩,数据压缩长于门槛的数据将被储存在压缩的形式
MClient.EnableCompression = false;
////压缩设置,超过指定大小的都压缩
//MClient.CompressionThreshold = 1024 * 1024;
} /// <summary>
/// 根据key存储对象
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool Set(string key, object value)
{
var result = MClient.Set(key, value);
return result;
} /// <summary>
/// 根据key存储对象,并且设置过期时间
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
public bool Set(string key, object value, DateTime timeOut)
{
var result = MClient.Set(key, value, timeOut);
return result;
} /// <summary>
/// 根据key获取对应的对象
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public object Get(string key)
{
var result = MClient.Get(key);
return result;
} /// <summary>
/// 替换对应key的value
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool Replace(string key, object value)
{
var result = MClient.Replace(key, value);
return result;
} /// <summary>
/// 删除对应key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool Delete(string key)
{
return MClient.Delete(key);
} /// <summary>
/// 删除对应key,并设置从内存中移除的时间点
/// </summary>
/// <param name="key"></param>
/// <param name="timeOut"></param>
/// <returns></returns>
public bool Delete(string key, DateTime timeOut)
{
return MClient.Delete(key, timeOut);
} /// <summary>
/// 判断key是否存在,存在返回true,不存在返回false
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool KeyExists(string key)
{
return MClient.KeyExists(key);
} /// <summary>
/// Memcache分布式锁
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns>当key存在返回false,当key不存在返回true</returns>
public bool Add(string key, object value)
{
return MClient.Add(key, value);
} /// <summary>
/// Memcache分布式锁,并且设置过期时间
/// Memcached分布式锁可以使用 Add 命令,该命令只有KEY不存在时,才进行添加,否则不会处理。Memcached 所有命令都是原子性的,并发下add 同一个KEY,只会一个会成功。
/// 利用这个原理,可以先定义一个锁 LockKEY,Add 成功的认为是得到锁。并且设置[过期超时] 时间,保证宕机后,也不会死锁。
/// 在完成具体操作后,判断锁 LockKEY 是否已超时。如果超时则不删除锁,如果不超时则 Delete 删除锁。
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="timeOut"></param>
/// <returns>当key存在返回false,当key不存在返回true</returns>
public bool Add(string key, object value, DateTime timeOut)
{
return MClient.Add(key, value, timeOut);
}
}
}

控制台程序:

//引用
using Memcached.ClientLibrary;
namespace Memcache.AddLock
{
/// <summary>
/// Memcache分布式锁简单实例
/// </summary>
public class Program
{
//创建一个公共类
public static MemcacheHelper memcache; public static void Main(string[] args)
{
memcache = new MemcacheHelper();
Console.WriteLine("线程开始前,输出" + memcache.Get("demoKey"));
var result = memcache.Delete("demoKey");
Console.WriteLine("线程开始前,输出" + memcache.Get("demoKey") + ",删除对应key返回:" + result);
Console.WriteLine("线程开始前,输出" + memcache.Delete("LockKey"));
memcache.Set("demoKey", "0");
//定义三个线程
Thread myThread1 = new Thread(new ParameterizedThreadStart(AddVal));
Thread myThread2 = new Thread(new ParameterizedThreadStart(AddVal));
Thread myThread3 = new Thread(AddVal);
myThread1.Start("1");
myThread2.Start("2");
myThread3.Start();
Console.WriteLine("等待两个线程结束");
Console.ReadKey();
} public static void AddVal(object num)
{
for (int i = 0; i < 500; i++)
{
//int result = int.Parse(memcache.Get("demoKey").ToString());
//memcache.Set("demoKey", (result + 1).ToString()); //如果0.5秒不释放锁 自动释放,避免死锁
if (memcache.Add("LockKey", "Hello World", DateTime.Now.AddSeconds(0.5)))
{
//得到锁
try
{
int result = int.Parse(memcache.Get("demoKey").ToString());
memcache.Set("demoKey", (result + 1).ToString()); //注意:这里最好加上主动去删除锁
//检查锁是否超时(直接去删除就可以)
memcache.Delete("LockKey");
}
catch (Exception ex)
{
//发生异常时也直接删除锁
memcache.Delete("LockKey");
}
}
else
{
i = i - 1; //没有得到锁时等待
}
}
Console.WriteLine("线程" + num + "结束,输出" + memcache.Get("demoKey"));
}
}
}

运行结果效果图说明:

图一是没有加分布式锁的情况下执行结果
 
图二是加分布式锁的情况下执行结果,三个线程各循环500次,最终缓存值应该为1500才正确

Memcache分布式锁 转发 https://www.cnblogs.com/li150dan/p/9529090.html的更多相关文章

  1. MemCache在.NET中使用Memcached.ClientLibrary详解 转发 https://www.cnblogs.com/li150dan/p/9529112.html

    本文说明:memcached分布式缓存的负载均衡配置比例,数据压缩,socket的详细配置等,以及在.net中的常用方法 首先下载客户端的3个dll,ICSharpCode.SharpZipLib.d ...

  2. Memcache分布式锁

    在分布式缓存的应用中,会遇到多个客户端同时争用的问题.这个时候,需要用到分布式锁,得到锁的客户端才有操作权限 下面通过一个简单例子介绍: 这里引用的是Memcached.ClientLibrary.d ...

  3. ElasticSearch(站内搜索) 转发 https://www.cnblogs.com/xibei666/p/5929970.html

    简介 Elasticsearch是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据.它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合.Elasticse ...

  4. .net core redis 驱动推荐,为什么不使用 StackExchange.Redis 转发 https://www.cnblogs.com/kellynic/p/9325816.html

    前言 本人从事 .netcore 转型已两年有余,对 .net core 颇有好感,这一切得益于优秀的语法.框架设计. 2006年开始使用 .net 2.0,从 asp.net 到 winform 到 ...

  5. Cordova入门系列(二)分析第一个helloworld项目 转发 https://www.cnblogs.com/lishuxue/p/6015420.html

    Cordova入门系列(二)分析第一个helloworld项目   版权声明:本文为博主原创文章,转载请注明出处 上一章我们介绍了如何创建一个cordova android项目,这章我们介绍一下创建的 ...

  6. Cordova入门系列(三)Cordova插件调用 转发 https://www.cnblogs.com/lishuxue/p/6018416.html

    Cordova入门系列(三)Cordova插件调用   版权声明:本文为博主原创文章,转载请注明出处 上一章我们介绍了cordova android项目是如何运行的,这一章我们介绍cordova的核心 ...

  7. Cordova入门系列(一)创建项目 转发 https://www.cnblogs.com/lishuxue/p/6008678.html

    版权声明:本文为博主原创文章,转载请注明出处 Cordova是什么? 初学Cordova的人,虽然了解一点点,知道Cordova是用来将html, css, js变成app的,但并不知道到底是怎么用的 ...

  8. ActiveMQ安装配置及使用 转发 https://www.cnblogs.com/hushaojun/p/6016709.html

    ActiveMQ安装配置及使用 ActiveMQ介绍 ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JM ...

  9. Topshelf:一款非常好用的 Windows 服务开发框架 转发https://www.cnblogs.com/happyframework/p/3601995.html

    背景 多数系统都会涉及到“后台服务”的开发,一般是为了调度一些自动执行的任务或从队列中消费一些消息,开发 windows service 有一点不爽的是:调试麻烦,当然你还需要知道 windows s ...

随机推荐

  1. idea使用svn出现问题解决办法

    idea一直在refreshing vcs history:解决办法:      有些模块中的版本信息是错的,如拷贝过来的代码,其远程仓库是不存在的,      因此要删除这些模块中的.svn文件夹 ...

  2. 《JavaScript高级程序设计》笔记:变量、作用域和内存问题(四)

    基本类型和引用类型的值 ECMAScript变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型的值指那些可能有多个值构成的对象. 动态的属性 var p ...

  3. 在“非软件企业”开发软件的困局 ZT

    软件产品广泛服务于各行业,其开发具有高科技.高投入.高产出.高风险的特点.在项目开发和软件应用中,只有将人员能力的发挥与科学技术的使用应用市场的认识进行最佳的融合,才能发挥软件的效益.普通企业虽涉足软 ...

  4. 转载:如何在Ubuntu 18.04上使用UFW设置防火墙

    https://blog.csdn.net/u013068789/article/details/82051943 介绍 UFW或Uncomplicated Firewall是iptables一个接口 ...

  5. matlab练习程序(局部加权线性回归)

    通常我们使用的最小二乘都需要预先设定一个模型,然后通过最小二乘方法解出模型的系数. 而大多数情况是我们是不知道这个模型的,比如这篇博客中z=ax^2+by^2+cxy+dx+ey+f 这样的模型. 局 ...

  6. centos7安装jdk环境

    有时候安装一些软件或者服务都需要jdk环境,今天就在centos上安装最新的jdk环境. 检测历时安装 1.查看Linux自带的JDK是否已安装 # java -version 2.查看JDK信息 # ...

  7. NAT穿越(一) NAT类型

    NAT分为四种类型: (1)完全透明NAT(Full Cone NAT): 从内部主机  (IN IP ipa) +端口(IN PORT porta) 发送的数据映射为  IP(OUT IP IPA) ...

  8. Linux 最小化安装后IP的配置(DHCP获取IP地址)

    图形化Linux的DHCP好配置,我就不讲了.主要将一下Linux最小化安装后IP的配置: linux最小化安装后没有ifconfig这个命令: yum install net-tools.x86_6 ...

  9. C# 实体/集合差异比较,比较两个实体或集合值是否一样,将实体2的值动态赋值给实体1(名称一样的属性进行赋值)

    /// <summary> /// 实体差异比较器 /// </summary> /// <param name="source">源版本实体& ...

  10. Windows Server 2016-Nano Server介绍

    WindowsServer 2016 提供了新的安装选项:Nano Server.Nano Server 是针对私有云和数据中心进行优化的远程管理的服务器操作系统. 类似于 Windows Serve ...