读/写锁的实现和应用(高并发状态下的map实现)
程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。
按照上面的叙述,简单的实现出一个读/写锁
- public class ReadWriteLock{
- private int readers = ;
- private int writers = ;
- private int writeRequests = ;
- public synchronized void lockRead()
- throws InterruptedException{
- while(writers > || writeRequests > ){
- wait();
- }
- readers++;
- }
- public synchronized void unlockRead(){
- readers--;
- notifyAll();
- }
- public synchronized void lockWrite()
- throws InterruptedException{
- writeRequests++;
- while(readers > || writers > ){
- wait();
- }
- writeRequests--;
- writers++;
- }
- public synchronized void unlockWrite()
- throws InterruptedException{
- writers--;
- notifyAll();
- }
- }
ReadWriteLock类中,读锁和写锁各有一个获取锁和释放锁的方法。
可重入的ReadWriteLock的完整实现
下面是完整的ReadWriteLock实现。为了便于代码的阅读与理解,简单对上面的代码做了重构。重构后的代码如下。
- public class ReadWriteLock{
- private Map<Thread, Integer> readingThreads =
- new HashMap<Thread, Integer>();
- private int writeAccesses = ;
- private int writeRequests = ;
- private Thread writingThread = null;
- public synchronized void lockRead()
- throws InterruptedException{
- Thread callingThread = Thread.currentThread();
- while(! canGrantReadAccess(callingThread)){
- wait();
- }
- readingThreads.put(callingThread,
- (getReadAccessCount(callingThread) + ));
- }
- private boolean canGrantReadAccess(Thread callingThread){
- if(isWriter(callingThread)) return true;
- if(hasWriter()) return false;
- if(isReader(callingThread)) return true;
- if(hasWriteRequests()) return false;
- return true;
- }
- public synchronized void unlockRead(){
- Thread callingThread = Thread.currentThread();
- if(!isReader(callingThread)){
- throw new IllegalMonitorStateException(
- "Calling Thread does not" +
- " hold a read lock on this ReadWriteLock");
- }
- int accessCount = getReadAccessCount(callingThread);
- if(accessCount == ){
- readingThreads.remove(callingThread);
- } else {
- readingThreads.put(callingThread, (accessCount -));
- }
- notifyAll();
- }
- public synchronized void lockWrite()
- throws InterruptedException{
- writeRequests++;
- Thread callingThread = Thread.currentThread();
- while(!canGrantWriteAccess(callingThread)){
- wait();
- }
- writeRequests--;
- writeAccesses++;
- writingThread = callingThread;
- }
- public synchronized void unlockWrite()
- throws InterruptedException{
- if(!isWriter(Thread.currentThread()){
- throw new IllegalMonitorStateException(
- "Calling Thread does not" +
- " hold the write lock on this ReadWriteLock");
- }
- writeAccesses--;
- if(writeAccesses == ){
- writingThread = null;
- }
- notifyAll();
- }
- private boolean canGrantWriteAccess(Thread callingThread){
- if(isOnlyReader(callingThread)) return true;
- if(hasReaders()) return false;
- if(writingThread == null) return true;
- if(!isWriter(callingThread)) return false;
- return true;
- }
- private int getReadAccessCount(Thread callingThread){
- Integer accessCount = readingThreads.get(callingThread);
- if(accessCount == null) return ;
- return accessCount.intValue();
- }
- private boolean hasReaders(){
- return readingThreads.size() > ;
- }
- private boolean isReader(Thread callingThread){
- return readingThreads.get(callingThread) != null;
- }
- private boolean isOnlyReader(Thread callingThread){
- return readingThreads.size() == &&
- readingThreads.get(callingThread) != null;
- }
- private boolean hasWriter(){
- return writingThread != null;
- }
- private boolean isWriter(Thread callingThread){
- return writingThread == callingThread;
- }
- private boolean hasWriteRequests(){
- return this.writeRequests > ;
- }
- }
应用:线程安全并且高并发状态下的map实现
- class RWDictionary {
- private final Map<String, Data> m = new TreeMap<String, Data>();
- private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
- private final Lock r = rwl.readLock();
- private final Lock w = rwl.writeLock();
- public Data get(String key) {
- r.lock();
- try { return m.get(key); }
- finally { r.unlock(); }
- }
- public String[] allKeys() {
- r.lock();
- try { return m.keySet().toArray(); }
- finally { r.unlock(); }
- }
- public Data put(String key, Data value) {
- w.lock();
- try { return m.put(key, value); }
- finally { w.unlock(); }
- }
- public void clear() {
- w.lock();
- try { m.clear(); }
- finally { w.unlock(); }
- }
- }
读/写锁的实现和应用(高并发状态下的map实现)的更多相关文章
- php高并发状态下文件的读写
php高并发状态下文件的读写 背景 1.对于PV不高或者说并发数不是很大的应用,不用考虑这些,一般的文件操作方法完全没有问题 2.如果并发高,在我们对文件进行读写操作时,很有可能多个进程对进一文件 ...
- C++高并发场景下读多写少的解决方案
C++高并发场景下读多写少的解决方案 概述 一谈到高并发的解决方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也 ...
- C++高并发场景下读多写少的优化方案
概述 一谈到高并发的优化方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也能很大的影响整体性能,本文从单模块下读 ...
- C# 防止同时调用=========使用读写锁三行代码简单解决多线程并发的问题
http://www.jb51.net/article/99718.htm 本文主要介绍了C#使用读写锁三行代码简单解决多线程并发写入文件时提示"文件正在由另一进程使用,因此该进程无 ...
- Java高并发情况下的锁机制优化
本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 1 public synchronized void syncMethod(){ 2 othercode ...
- 【高并发】高并发环境下构建缓存服务需要注意哪些问题?我和阿里P9聊了很久!
写在前面 周末,跟阿里的一个朋友(去年晋升为P9了)聊了很久,聊的内容几乎全是技术,当然了,两个技术男聊得最多的话题当然就是技术了.从基础到架构,从算法到AI,无所不谈.中间又穿插着不少天马行空的想象 ...
- 关于WCF服务在高并发情况下报目标积极拒绝的异常处理
最近弄了个wcf的监控服务,偶尔监控到目标服务会报一个目标积极拒绝的错误.一开始以为服务停止了,上服务器检查目标服务好好的活着.于是开始查原因. 一般来说目标积极拒绝(TCP 10061)的异常主要是 ...
- WCF服务在高并发情况下报目标积极拒绝的异常处理 z
http://www.cnblogs.com/kklldog/p/5037006.html wcf的监控服务,偶尔监控到目标服务会报一个目标积极拒绝的错误.一开始以为服务停止了,上服务器检查目标服务好 ...
- [转]高并发访问下避免对象缓存失效引发Dogpile效应
避免Redis/Memcached缓存失效引发Dogpile效应 Redis/Memcached高并发访问下的缓存失效时可能产生Dogpile效应(Cache Stampede效应). 推荐阅读:高并 ...
随机推荐
- 【Web】网站主如何更改网页标签的图标(favicon.ico)
修改web项目的favicon图标,方式有两种:全局方式和局部方式 全局方式: 进入服务器\webapps\ROOT,然后用自己的favicon.ico替换服务器自带的favicon.ico图片 局部 ...
- jsoup Java HTML解析器:使用选择器语法来查找元素
jsoup Java HTML解析器:使用选择器语法来查找元素 使用选择器语法来查找元素 问题 你想使用类似于CSS或jQuery的语法来查找和操作元素. 方法 可以使用Element.select( ...
- org.eclipse.ui.PartInitException: Unable to open editor, unknown editor ID: org.xmen.ui.text.XMLTextEditor
无法打开struts模式的编译xml的编译器,然后打开.project文件,编辑最后一行,找到<natures>结点,增加一条<nature>com.genuitec.ecli ...
- UVaLive 6525 Attacking rooks (二分图最大匹配)
题意:给定一个 n * n的图,X是卒, . 是空位置,让你放尽量多的车,使得他们不互相攻击. 析:把每行连续的 . 看成X集体的一个点,同理也是这样,然后求一个最大匹配即可. 代码如下: #prag ...
- BZOJ 1005 [HNOI2008]明明的烦恼 (Prufer编码 + 组合数学 + 高精度)
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5786 Solved: 2263[Submit][Stat ...
- HDU 3177 Crixalis's Equipment (贪心,差值)
题意:判断 n 件物品是否可以搬进洞里,每件物品有实际体积A和移动时的额外体积 B . 析:第一反应就是贪心,一想是不是按B从大到小,然后一想,不对,比如体积是20,第一个 是A=11, B=19.第 ...
- python 判断是否是空行或注释行
#coding:utf-8 '''''cdays-4-exercise-6.py 文件基本操作 @note: 文件读取写入, 列表排序, 字符串操作 @see: 字符串各方法可参考hekp(str)或 ...
- obj-c的优缺点
优点: 1) Cateogies : 类别 2) Posing : 扮演 3) 动态识别 : 编译时与运行时动态识别类型 4) 指标计算 : 指针计算 指针的 +- * / 5) 弹性信息传递 : 某 ...
- [转] ubuntu安装Sublime Text 3并使用SublimeClang插件
原文地址:https://blog.csdn.net/cywosp/article/details/32721011 3. 安装强大的SublimeClang插件 SublimeClang是Subli ...
- hdu1251 && hud 1247 (字典树)
hdu1251 题目 这道题,主要是在主函数的输入输出上犹豫了. #include<stdio.h> #include<cstring> #include<iostrea ...