读/写锁的实现和应用(高并发状态下的map实现)
来源:互联网 发布:忘羡捏脸数据 编辑:程序博客网 时间:2024/06/05 13:33
程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写(译者注:也就是说:读-读能共存,读-写不能共存,写-写不能共存)。这就需要一个读/写锁来解决这个问题。
按照上面的叙述,简单的实现出一个读/写锁
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<Thread, Integer> readingThreads = new HashMap<Thread, Integer>(); 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<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(); } } }
0 0
- 读/写锁的实现和应用(高并发状态下的map实现)
- 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁)
- 聊聊高并发(十五)实现一个简单的读-写锁(共享-排他锁)
- 缓存Map高并发下的访问
- 高并发的socket实现
- httpd高并发的实现
- 多核下的并发计数器的高性能实现
- 高并发下session写入redis的实现
- Redis实现高并发下的抢购、秒杀功能
- Redis实现高并发下的抢购、秒杀功能
- redis实现高并发下的抢购/秒杀功能
- Redis实现高并发下的抢购,秒杀,解决方案
- PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
- PHP和Redis实现在高并发下的抢购及秒杀功能
- Linux下的socket编程实践(九) epoll实现高并发的原理及其使用
- 构建高性能服务(二)java高并发锁的3种实现
- 构建高性能服务(二)java高并发锁的3种实现
- ConcurrentHashMap 高并发性的实现机制
- 微服务系统架构的优点与不足
- JIRA Rest JAVA Client API实现问题管理及自定义字段(原创)
- 编写线程安全的Java缓存读写机制 (原创)
- 使用泛型SwingWorker与EDT事件分发线程保持通讯
- Jira API传字符串的换行问题 (文本编辑器使用)
- 读/写锁的实现和应用(高并发状态下的map实现)
- 替换元素节点replaceChild()
- (原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
- (转)ReentrantLock可重入锁的使用场景
- AIX系统查看apache版本号
- (原创)确保JAVA线程安全的4种常用方法
- JAVA线程本地变量ThreadLocal和私有变量的区别
- (原创)定时线程池中scheduleWithFixedDelay和scheduleAtFixedRate的区别
- autovideoplayer