读写锁的判定和可重入性
发布日期:2021-06-29 03:45:04
浏览次数:2
分类:技术文章
本文共 4235 字,大约阅读时间需要 14 分钟。
看了一个很好的关于读写线程的设计,支持可重入,代码写的很好,优秀的代码总是需要慢慢的专研和学习的,嘿嘿
package com.zcswl.syn;import java.util.HashMap;import java.util.Map;/** * 读线程不能够阻塞读线程, * 当前的读线程能够阻塞其他线程的写线程,自身拥有写线程 * 当前的写线程能够阻塞其他线程的读线程,自身拥有读线程,并且可重复获取当前的写线程 * @author zhouchenggong * */public class ReadWriterLockFinal { private MapreadingThreads =new HashMap (); //读线程Map集合 private int writeAccesses = 0;//写标志 private int writeRequests = 0;//写请求 private Thread writingThread = null;//写线程 public synchronized void lockRead() throws InterruptedException{ Thread callingThread = Thread.currentThread(); while(! canGrantReadAccess(callingThread)){ wait(); } /** * 将当前的读线程加入到读线程的Map集合中,设置当前线程在集合中的int值 */ readingThreads.put(callingThread, (getReadAccessCount(callingThread) + 1)); } 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"); } /** * 在读线程的Map中获取,如果为1,表示的是读写第一次 */ int accessCount = getReadAccessCount(callingThread); if(accessCount == 1){ readingThreads.remove(callingThread); } else { //Map中没有改线程,加入进去 readingThreads.put(callingThread, (accessCount -1)); } 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 == 0){ 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 0; return accessCount.intValue(); } private boolean hasReaders(){ return readingThreads.size() > 0; } private boolean isReader(Thread callingThread){ return readingThreads.get(callingThread) != null; } private boolean isOnlyReader(Thread callingThread){ return readingThreads.size() == 1 && readingThreads.get(callingThread) != null; } //如果写线程不是null,true; private boolean hasWriter(){ return writingThread != null; } //如果当前的线程是写线程,true; private boolean isWriter(Thread callingThread){ return writingThread == callingThread; } private boolean hasWriteRequests(){ return this.writeRequests > 0; }}
转载地址:https://blog.csdn.net/zcswl7961/article/details/68487441 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2024年04月07日 21时01分09秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
python网页解析器
2019-04-29
linux安装svn并设置自启动
2019-04-29
svn常用命令
2019-04-29
python2网页采集案例
2019-04-29
svn的服务端配置
2019-04-29
python3 urllib和requests模块
2019-04-29
Axure常见的几种原型图
2019-04-29
svn的checkout与export的区别与使用
2019-04-29
js实现点击复制功能
2019-04-29
phpquery采集案例
2019-04-29
jsp内置对象request的常用方法
2019-04-29
javascript 0和-0
2019-04-29
iView3.0样式显示问题(Select和DatePicker)
2019-04-29
Gulp常用的一些插件
2019-04-29
Docker:基础知识
2019-04-29
mysql知识总结
2019-04-29
C#连接ACCESS
2019-04-29
linux安装VMtools
2019-04-29
移动硬盘插入win10检测到却不显示盘符解决方法
2019-04-29
怎么查看本机S/N序列号和BIOS版本
2019-04-29