• 多线程先判断再操作免锁设计方案


    近日,业务上要求要对一块缓存进行高效率的读写。一开始采用了读写锁的设计,后来发现单个线程单次需要进行成千上万次的读,导致了过多的加解锁的开销,效率实在不敢恭维。加锁的主要原因是多线程先判断再操作导致判定失效问题,最近一直在考虑如何进行免锁设计,结合之前看过的final内存语义,设计了一个没有锁的实现方式,然后用了一万个线程进行并发测试,暂时通过了测试,下面说说我的思路,如果有问题,大家可以狂喷一下。

    首先读写锁的方式,大家应该是没问题的。我先阐述一下问题。

    由上图可以看出,线程1判定的状态在读取缓存时已经失效了,导致读取的时候得到空指针异常。

    下面是我的demo代码

    public class NoLockCache{
        private class Lock {
            private final boolean isValid;
            private final HashMap<Integer, Integer> hashMap;
            public Lock(boolean isValid, HashMap<Integer, Integer> hashMap) {
                this.isValid = isValid;
                this.hashMap = hashMap;
            }
            public Integer get() {
                if (isValid) {
                    LockSupport.parkNanos(10000000);
                    return hashMap.get(1);
                } else {
                    return 0;
                }
            }
        }
     
        private volatile Lock lock;
     
        public NoLockCache() {
            HashMap<Integer, Integer> hashMap = new HashMap<>();
            hashMap.put(1, 1);
            lock = new Lock(true, hashMap);
        }
     
        public Integer get() {
            return lock.get();
        }
     
        public void release() {
            lock = new Lock(false, new HashMap<>());
            HashMap<Integer, Integer> hashMap = new HashMap<>();
            hashMap.put(1, 1);
            lock = new Lock(true, hashMap);
        }
    }
    

      

    免锁设计
     

    上面NoLockCache的get操作,委托给内部类Lock。

    Lock的两个成员变量都是final类型的,这两个final类型的变量可以保证在初始化Lock时,isValid和缓存hashMap处在一个一致的状态(可以参考并发编程艺术第三章的final语义或者博客http://www.cnblogs.com/CLFR/p/6262433.html),别的线程看到Lock只有两个状态,isValid是false且缓存是空,或者isValid是true且缓存被填充状态。有人会说了,那Lock的get方法不也是先判断,再操作吗?其实这时候的Lock已经加载在栈中,这时候的Lock方法get结束前,Lock会维持一个快照的状态,不会抛出NPE。

  • 相关阅读:
    webDriver自动化操作(二)浏览器/页面信息属性操作
    webDriver自动化操作(一)元素定位和基础操作
    Selenium(一) Selenium和ChromeDriver的安装与配置
    Fiddler设置爬取app网页
    pycharm新建项目配置虚拟环境
    AIRTEST安装配置流程
    Jquery树插件zTree学习总结
    HTML中head标签内的使用标签详解
    Highcharts图表学习(二)
    noty-jQuery插件
  • 原文地址:https://www.cnblogs.com/CLFR/p/6491573.html
Copyright © 2020-2023  润新知