ReentrantReadWriteLock可重入读写锁使用
2015-11-13 11:38
387 查看
特点
可重入:就是同一个线程可以重复加锁,可以对同一个锁加多次,每次释放的时候回释放一次,直到该线程加锁次数为0,这个线程才释放锁。比如同一个线程中可以对同一个锁加多次写入锁。写线程获取写入锁后可以再次获取读取锁,但是读线程获取读取锁后却不能获取写入锁。读写锁: 也就是读锁可以共享,多个线程可以同时拥有读锁,但是写锁却只能只有一个线程拥有,而且获取写锁的时候,其他线程都已经释放了读锁,而且在该线程获取写锁之后,其他线程不能再获取读锁。
锁降级:写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现锁降级的特性。
锁升级:读取锁是不能直接升级为写入锁的。因为获取一个写入锁需要释放所有读取锁,所以如果有两个读取锁试图获取写入锁而都不释放读取锁时就会发生死锁。
重入数:读取锁和写入锁的数量最大分别只能是65535(包括重入数)
锁获取中断:读取锁和写入锁都支持获取锁期间被中断。这个和独占锁一致。
示例
下面是源码中提供的示例:* class CachedData { * Object data; * volatile boolean cacheValid; * final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); * * void processCachedData() { * rwl.readLock().lock(); * if (!cacheValid) { * // Must release read lock before acquiring write lock * rwl.readLock().unlock(); * rwl.writeLock().lock(); * try { * // Recheck state because another thread might have * // acquired write lock and changed state before we did. * if (!cacheValid) { * data = ... * cacheValid = true; * } * // Downgrade by acquiring read lock before releasing write lock * rwl.readLock().lock(); * } finally { * rwl.writeLock().unlock(); // Unlock write, still hold read * } * } * * try { * use(data); * } finally { * rwl.readLock().unlock(); * } * } * }
* 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(); } * } * }
相关文章推荐
- PHP json_encode
- java微信开发高级接口----群发功能
- 使用spring @Scheduled注解执行定时任务
- MAC复制 压缩 拷贝报错:编码错误8058解决方案
- 友盟社会化分享
- Android Studio 中Intel HAXM安装与模拟器创建
- PowerDesigner导出表到word
- hdu 1262寻找素数对
- Android的应用名本地化
- CSS3 Media Queries
- hdu 1262寻找素数对
- Thinkphp3.2 PHPMailer 发送 QQ邮箱 163邮箱
- 从头认识java-8.9 嵌套类(使用static的内部类)
- android平台的视频播放器中需要的屏幕滑动源代码.
- mesos+marathon+zookeeper的docker管理集群亲手搭建实例(详细)
- AppleScript 的一些命令
- const小结
- 利用IText生成PDF时图片,位置错乱的问题
- 64位下无法使用Microsoft.Jet.OLEDB.4.0的解决方法
- [转载]目前流行的缺陷管理工具