zoukankan      html  css  js  c++  java
  • 高性能的StampedLock锁

    StampedLock 支持的三种锁模式:

    1.ReadWriteLock 支持两种模式:一种是读锁,一种是写锁
    
    2.StampedLock 支持三种模式,分别是:写锁、悲观读锁和乐观读
        1)写锁、悲观读锁的语义和 ReadWriteLock 的写锁、读锁的语义非常类似,
        2)允许多个线程同时获取悲观读锁,但是只允许一个线程获取写锁,写锁和悲观读锁是互斥的
        3)不同的是:StampedLock 里的写锁和悲观读锁加锁成功之后,都会返回一个 stamp;然后解锁的时候,需要传入这个 stamp
    import java.util.concurrent.locks.LockSupport;
    import java.util.concurrent.locks.StampedLock;
    
    class Point {
        public static void main(String[] args) throws InterruptedException {
            final StampedLock lock = new StampedLock();
            Thread T1 = new Thread(()->{
                // 获取写锁
                lock.writeLock();
                // 永远阻塞在此处,不释放写锁
                LockSupport.park();
            });
            T1.start();
            // 保证T1获取写锁
            Thread.sleep(100);
            Thread T2 = new Thread(()->
                    //阻塞在悲观读锁
                    lock.readLock()
            );
            T2.start();
            // 保证T2阻塞在读锁
            Thread.sleep(100);
            //中断线程T2
            //会导致线程T2所在CPU飙升
            T2.interrupt();
            T2.join();
        }
    }

    分析:

    1.线程 T1 获取写锁之后将自己阻塞,线程 T2 尝试获取悲观读锁,也会阻塞;
    
    2.此时调用线程 T2 的 interrupt() 方法来中断线程 T2 的话,你会发现线程 T2 所在 CPU 会飙升到 100%3.所以,使用 StampedLock 一定不要调用中断操作,
        如果需要支持中断功能,一定使用可中断的悲观读锁 readLockInterruptibly() 和写锁 writeLockInterruptibly()

    使用 StampedLock的最佳实践demo:

    StampedLock 读模板:

    import java.util.concurrent.locks.StampedLock;
    
    class Point {
        public static void main(String[] args) throws InterruptedException {
            final StampedLock sl = new StampedLock();
    
            // 乐观读
            long stamp = sl.tryOptimisticRead();
            // 读入方法局部变量
            ......
            // 校验stamp
            if (!sl.validate(stamp)){
                // 升级为悲观读锁
                stamp = sl.readLock();
                try {
                    // 读入方法局部变量
                    .....
                } finally {
                    //释放悲观读锁
                    sl.unlockRead(stamp);
                }
            }
            //使用方法局部变量执行业务操作
            ......
        }
    }

    StampedLock 写模板:

    import java.util.concurrent.locks.StampedLock;
    
    class Point {
        public static void main(String[] args) throws InterruptedException {
            final StampedLock sl = new StampedLock();
            long stamp = sl.writeLock();
            try {
                // 写共享变量
                ......
            } finally {
                sl.unlockWrite(stamp);
            }
        }
    }
  • 相关阅读:
    luogu P3804 【模板】后缀自动机 (SAM)
    莫队
    luogu P4688 [Ynoi2016]掉进兔子洞
    FZOJ 2331 LYK loves graph
    字典树
    luogu P6623 [省选联考 2020 A 卷] 树
    luogu P6018 [Ynoi2010]Fusion tree
    luogu P3264 [JLOI2015]管道连接
    最小斯坦纳树
    9. 回文数
  • 原文地址:https://www.cnblogs.com/big-cut-cat/p/13536325.html
Copyright © 2011-2022 走看看