ReentrantReadWriteLock最最最经典示例用法

下面的代码展示了如何利用重入来执行升级缓存后的锁降级(为简单起见,省略了异常处理):

class CachedData {
   Object data;
   volatile boolean cacheValid;
   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();
        // 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();
        rwl.writeLock().unlock(); // Unlock write, still hold read
     }

     use(data);
     rwl.readLock().unlock();
   }
 }

在使用某些种类的 Collection 时,可以使用 ReentrantReadWriteLock 来提高并发性。通常,在预期 collection 很大,读取者线程访问它的次数多于写入者线程,并且 entail 操作的开销高于同步开销时,这很值得一试。例如,以下是一个使用 TreeMap 的类,预期它很大,并且能被同时访问。

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(); }
    }
 }

原文地址:http://blog.51cto.com/viphyy/2092670

时间: 2024-11-09 01:52:36

ReentrantReadWriteLock最最最经典示例用法的相关文章

C# 多线程经典示例 吃苹果

本文主要讲述了多线程开发中经典示例,通过本示例,可以加深对多线程的理解. 示例概述: 下面用一个模拟吃苹果的实例,说明C#中多线程的实现方法.要求开发一个程序实现如下情况:一个家庭有三个孩子,爸爸妈妈不断削苹果往盘子里面放,老大.老二.老三不断从盘子里面取苹果吃.盘子的大小有限,最多只能放5个苹果,并且爸妈不能同时往盘子里面放苹果,妈妈具有优先权.三个孩子取苹果时,盘子不能为空,三人不能同时取,老三优先权最高,老大最低.老大吃的最快,取的频率最高,老二次之. 涉及到知识点: 线程Thread 创

Android(java)回调函数经典示例

回调函数经典示例 1.使用java回调函数来实现一个测试函数运行时间的工具类 public class TestObject { /** * 一个用来被测试的方法,进行了一个比较耗时的循环 */ public static void testMethod(){ for ( int i= 0 ; i< 100000000 ; i++){ } } /** * 一个简单的测试方法执行时间的方法 */ public void testTime(){ long begin = System.current

进程同步经典示例 多线程上篇(五)

同步回顾 进程同步控制有多种方式:算法.硬件.信号量.管程 这些方式可以认为就是同步的工具(方法.函数) 比如信号量机制中的wait(S) 和 signal(S) ,就相当于是两个方法调用. 调用wait(S)就会申请这个资源,否则就会等待(进入等待队列):调用signal(S)就会释放资源(或一并唤醒等待队列中的某个): 在梳理同步问题的解决思路时,只需要合理安排方法调用即可,底层的实现细节不需要关注. 接下来以这种套路,看一下借助与不同的同步方式“算法.硬件.信号量.管程”这一“API”,如

Android 经典示例,初学者的绝好源码资料

这是我根据自己的良好习惯,把网络上的经典Android 案例组织在一个工程中.对于Android 学习者有很好的好处.欢迎大家把这个示例项目越做越大.为后来的新人积累财富.发扬前人种树,后人乘凉的精神.想学更多的Android应用开发方面的知识请访问e良师益友.

25个iptables非常经典的用法

本文介绍25个常用的iptables用法.如果你对iptables还不甚了解,可以参考上一篇iptables详细教程:基础.架构.清空规则.追加规则.应用实例,看完这篇文章,你就能明白iptables的用法和本文提到的基本术语. 一.iptables:从这里开始 删除现有规则 iptables -F    (OR)  iptables --flush 设置默认链策略 iptables的filter表中有三种链:INPUT, FORWARD和OUTPUT.默认的链策略是ACCEPT,你可以将它们设

HTML经典标签用法

1.marquee属性的使用说明 <marquee> ... </marquee>移动属性的设置 ,这种移动不仅仅局限于文字,也可以应用于图片,表格等等 鼠标属性 onMouseOut=this.start() ........鼠标移出状态滚动 onMouseOver=this.stop() .........鼠标经过时停止滚动 方向<direction=#> #=left, right ,up ,down <marquee direction=left>从

单例经典示例

package com.etc.jichu; public class Singleton { //初始化为null的单例,用关键字volatile(不稳定的)修饰 private static volatile Singleton single=null; //私有的构造方法 private Singleton(){} public static Singleton getSingleton() { //如果当前实例为null则创建对象 if(single==null) { synchroni

Echarts经典示例

http://gallery.echartsjs.com/editor.html?c=xrkeZYLl6G http://gallery.echartsjs.com/editor.html?c=xSJpN0Ztig http://gallery.echartsjs.com/editor.html?c=xH1bfMkauM http://gallery.echartsjs.com/editor.html?c=xBJHFZ3Xof 更多查看:http://gallery.echartsjs.com/

【SQL】ROW_NUMBER() OVER(partition by 分组列 order by 排序列)用法详解+经典实例

原文:[SQL]ROW_NUMBER() OVER(partition by 分组列 order by 排序列)用法详解+经典实例 #用法说明 select row_number() over(partition by A order by B ) as rowIndex from table A :为分组字段 B:为分组后的排序字段. table 表的结构 多为:  多人 多条的相关数据.(比如:订单信息) 此条sql语句,多用于对数据进行分组排序,并对每个组中的数据分别进行编号,编号从1开始