技术笔记:Delphi多线程应用读写锁
在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性。也就是所谓的线程安全。之前写过一篇着于Java线程安全的博客:链接
我是在写一个服务端程序时应用到读写锁,在一个内存缓存。先来看看排斥锁的写法,代码如下:
function TValueCalc.GetValue(const key: string): TCache;
var
objCache: TCache;
begin
Result := nil;
//加锁
FRead2Lock.Enter;
try
objCache := GetCacheInstance.GetCache(sKey);
if objCache <> nil then
begin
//缓存正在更新,直接退出,不让线程等待,以提高性能
if objCache.IsUpdating then
Exit;
//是否过期,未过期直接返回
if MilliSecondsBetween(Now, objCache.LastTime) < Expires then
begin
Result := objCache;
Exit;
end; objCache.IsUpdating := True;
end;
//更新缓存
Result := UpdateCache(key);
finally
//释放锁
FRead2Lock.Leave;
end;
end;
但是这个缓存有一个特点,就是每个缓存项存活的时间很短,这就会导致大量的缓存更新操作,而这些更新操作由于业务不同耗时也不同。这就导致线程都在等待缓存的更新。为了解决这个问题引入了读写锁。让读锁可以在写数据时释放,让后面的线程继续执行查找缓存数据。
function TValueCalc.GetValue(const key: string): TCache;
var
objCache: TCache;
begin
Result := nil;
FRead2Lock.Enter;
try
objCache := GetCacheInstance.GetCache(sKey);
if objCache <> nil then
begin
//缓存正在更新,直接退出,不让线程等待,以提高性能
if objCache.IsUpdating then
Exit;
//检查缓存是否过期
if MilliSecondsBetween(Now, objCache.LastTime) < Expires then
begin
Result := objCache;
Exit;
end; objCache.IsUpdating := True;
end; //先释放读锁,后面线程可以继续读数据
FRead2Lock.Leave;
//加写锁
FWriteLock.Enter;
try
//更新缓存
Result := UpdateCache(key);
finally
//数据更新完毕,重新加上读锁
FRead2Lock.Enter;
//释放写锁
FWriteLock.Leave;
end;
finally
//释放读锁
FRead2Lock.Leave;
end;
end;
读写锁是在进行写数据前先释放掉读锁,然后马上加上写锁,这样后续读缓存的线程就可以继续执行,不会等待。而同时写缓存已经上锁,这样就不会资源冲突。
读写锁这样就可以大大提升读缓存的性能,也不会影响到缓存的更新了。
技术笔记:Delphi多线程应用读写锁的更多相关文章
- Java多线程之读写锁机制
Java多线程中有很多的锁机制,他们都有各自的应用场景,例如今天我说的这种锁机制:读写锁 读写锁,见名知意,主要可以进行两种操作,读和写操作,他们之间结合使用起来又是各不相同的.比如多个线程之间可以同 ...
- java多线程 -- ReadWriteLock 读写锁
写一条线程,读多条线程能够提升效率. 写写/读写 需要“互斥”;读读 不需要互斥. ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作.只要没有 writer,读取锁 ...
- java 多线程 day12 读写锁
import java.util.Random;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent. ...
- 用读写锁三句代码解决多线程并发写入文件 z
C#使用读写锁三句代码简单解决多线程并发写入文件时提示“文件正在由另一进程使用,因此该进程无法访问此文件”的问题 在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三 ...
- C#使用读写锁三行代码简单解决多线程并发写入文件时线程同步的问题
(补充:初始化FileStream时使用包含文件共享属性(System.IO.FileShare)的构造函数比使用自定义线程锁更为安全和高效,更多内容可点击参阅) 在开发程序的过程中,难免少不了写入错 ...
- C# 防止同时调用=========使用读写锁三行代码简单解决多线程并发的问题
http://www.jb51.net/article/99718.htm 本文主要介绍了C#使用读写锁三行代码简单解决多线程并发写入文件时提示"文件正在由另一进程使用,因此该进程无 ...
- C#使用读写锁解决多线程并发写入文件时线程同步的问题
读写锁是以 ReaderWriterLockSlim 对象作为锁管理资源的,不同的 ReaderWriterLockSlim 对象中锁定同一个文件也会被视为不同的锁进行管理,这种差异可能会再次导致文件 ...
- c++ 读写锁
#ifndef THREAD_UTIL_H #define THREAD_UTIL_H #include <pthread.h> namespace spider { class Auto ...
- Linux程序设计学习笔记----多线程编程线程同步机制之相互排斥量(锁)与读写锁
相互排斥锁通信机制 基本原理 相互排斥锁以排他方式防止共享数据被并发訪问,相互排斥锁是一个二元变量,状态为开(0)和关(1),将某个共享资源与某个相互排斥锁逻辑上绑定之后,对该资源的訪问操作例如以下: ...
随机推荐
- 深入研究Visual studio 2017 RC新特性
在[Xamarin+Prism开发详解三:Visual studio 2017 RC初体验]中分享了Visual studio 2017RC的大致情况,同时也发现大家对新的Visual Studio很 ...
- PHP之购物车的代码
该文章记录了购物车的实现代码,仅供参考 book_sc_fns.php <?php include_once('output_fns.php'); include_once('book_fns. ...
- 在你的ASP.NET MVC中使用查找功能
在程序中,使用查找功能是少之不了.今天在ASP.NET环境下演示一回. 在cshtml视图中,有三个文本框,让用户输入关键词,然后点击最右连的“搜索”铵钮,如果有结果将显示于下面. Html: 表格放 ...
- 基于NPOI的Excel数据导入
从Excel导入数据最令人头疼的是数据格式的兼容性,特别是日期类型的兼容性.为了能够无脑导入日期,折腾了一天的NPOI.在经过测试确实可以导入任意格式的合法日期后,写下这篇小文,与大家共享.完整代码请 ...
- Node.js入门
开始之前,安利一本正在看的书<站在两个世界的边缘>,作者程浩,上帝丢给他太多理想,却忘了给他完成理想的时间.OK,有兴趣的可以看一看. node.js如标题一样,我也是刚开始接触,大家一起 ...
- SAP CRM 性能小技巧
导言 本页面打算收集SAP CRM实施中可以用于避免性能问题的注意事项,重要的事项会由图标标识. 如果你有其他的技巧想要说出来,别犹豫! 性能注意事项 通用 缓存读取类访问,特别是在性能关键的地方,比 ...
- 网站缓存技术总结( ehcache、memcache、redis对比)
网站技术高速发展的今天,缓存技术已经成为大型网站的一个关键技术,缓存设计好坏直接关系的一个网站访问的速度,以及购置服务器的数量,甚至影响到用户的体验. 网站缓存按照存放的地点不同,可以分为客户端缓存. ...
- MonoDevelop 4.0.9 on CentOS 6.3 安装笔记
前言 Mono的前东家Novell公司旗下的SUSE Linux系列对Mono及MonoDevelop提供内置支持,所以在SUSE/OpenSUSE这些Linux系统中安装MonoDevelop是非常 ...
- mono for android 获取手机照片或拍照并裁剪保存
axml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...
- opengl 笔记(1)
参考<opengl入门教程>.<OpenGL之坐标转换>.<OpenGL绘制管线操作细节>等资料. 复习下留个备忘:) /*- * Opengl Demo Test ...