zoukankan      html  css  js  c++  java
  • 多线程先判断再操作免锁设计方案

    近日,业务上要求要对一块缓存进行高效率的读写。一开始采用了读写锁的设计,后来发现单个线程单次需要进行成千上万次的读,导致了过多的加解锁的开销,效率实在不敢恭维。加锁的主要原因是多线程先判断再操作导致判定失效问题,最近一直在考虑如何进行免锁设计,结合之前看过的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。

  • 相关阅读:
    faster with MyISAM tables than with InnoDB or NDB tables
    w-BIG TABLE 1-toSMALLtable @-toMEMORY
    Indexing and Hashing
    MEMORY Storage Engine MEMORY Tables TEMPORARY TABLE max_heap_table_size
    controlling the variance of request response times and not just worrying about maximizing queries per second
    Variance
    Population Mean
    12.162s 1805.867s
    situations where MyISAM will be faster than InnoDB
    1920.154s 0.309s 30817
  • 原文地址:https://www.cnblogs.com/CLFR/p/6491573.html
Copyright © 2011-2022 走看看