博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
读/写锁的实现和应用(高并发状态下的map实现)
阅读量:7117 次
发布时间:2019-06-28

本文共 4621 字,大约阅读时间需要 15 分钟。

程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。

按照上面的叙述,简单的实现出一个读/写锁

public class ReadWriteLock{  private int readers = 0;  private int writers = 0;  private int writeRequests = 0;  public synchronized void lockRead()      throws InterruptedException{      while(writers > 0 || writeRequests > 0){          wait();      }      readers++;  }  public synchronized void unlockRead(){      readers--;      notifyAll();  }  public synchronized void lockWrite()      throws InterruptedException{      writeRequests++;      while(readers > 0 || writers > 0){          wait();      }      writeRequests--;      writers++;  }  public synchronized void unlockWrite()      throws InterruptedException{      writers--;      notifyAll();  }}

 

 

ReadWriteLock类中,读锁和写锁各有一个获取锁和释放锁的方法。

 

可重入的ReadWriteLock的完整实现

下面是完整的ReadWriteLock实现。为了便于代码的阅读与理解,简单对上面的代码做了重构。重构后的代码如下。

public class ReadWriteLock{ private Map
readingThreads = new HashMap
(); 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(); } 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"); } int accessCount = getReadAccessCount(callingThread); if(accessCount == 1){ readingThreads.remove(callingThread); } else { 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; } private boolean hasWriter(){ return writingThread != null; } private boolean isWriter(Thread callingThread){ return writingThread == callingThread; } private boolean hasWriteRequests(){ return this.writeRequests > 0; }}

应用:线程安全并且高并发状态下的map实现

class RWDictionary {    private final Map
m = new TreeMap
(); 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(); } } }

 

转载地址:http://pyfel.baihongyu.com/

你可能感兴趣的文章
浅谈微信三级分销系统的漏洞
查看>>
linux系统目录详解
查看>>
读《大型企业信息系统的架构设计》分享,附下载
查看>>
.net 调用API并解析Json数据方法
查看>>
SpringBoot 使用ApplicationListener监听器
查看>>
那年的飘雪
查看>>
AngularJs学习笔记--I18n/L10n
查看>>
什么是Docker?
查看>>
MySQL Index
查看>>
PAT 1012
查看>>
Android 实现轮播效果(利用开源控件)
查看>>
-webkit-appearance改变按钮或其他空间的外观
查看>>
当前时间 格式
查看>>
FreeBSD 10 + Nginx 1.4.4 + PHP 5.5.9 + MySQL 5.6.1
查看>>
hadoop 排重优化
查看>>
用 VC++建立 Windows 服务程序
查看>>
服务器安全狗V4.1.08789发布 完善爬虫白名单库
查看>>
$_SERVER
查看>>
ubuntu日常使用
查看>>
设置kExtAudioFileProperty_ClientDataFormat报错
查看>>