【Java】StampedLock浅谈

1,概述

在多读少写的环境,相比于ReadWriteLoock,StampedLock性能更胜一筹。试着想一下,如果使用ReadWriteLoock,当1万个读请求过来时,写的操作插入,就会被阻塞。但StampedLock不会,后者不基于AQS实现,它采用乐观锁的思维。所谓的乐观,即读取的时候,不会阻塞当前线程,相应会返回一个邮票,state。读取完毕后,只要验证手上的邮票判断数据是否变化即可,随后决定去重新读取数据。本文笔者简单讲下StampedLock的实现思路,以供参考。

2,官方实例

class Point {
        private double x, y;
        private final StampedLock sl = new StampedLock();      // an exclusively locked method

        void move(double deltaX, double deltaY) {
            long stamp = sl.writeLock();
            try {
                x += deltaX;
                y += deltaY;
            } finally {
                sl.unlockWrite(stamp);
            }
        }      // a read-only method    // upgrade from optimistic read to read lock    

        double distanceFromOrigin() {
            long stamp = sl.tryOptimisticRead();
            try {
                retryHoldingLock:
                for (; ; stamp = sl.readLock()) {
                    if (stamp == 0L) continue retryHoldingLock;
                    // possibly racy reads
                    double currentX = x;
                    double currentY = y;
                    if (!sl.validate(stamp)) continue retryHoldingLock;
                    return Math.hypot(currentX, currentY);
                }
            } finally {
                if (StampedLock.isReadLockStamp(stamp)) sl.unlockRead(stamp);
            }
        }      // upgrade from optimistic read to write lock    

        void moveIfAtOrigin(double newX, double newY) {
            long stamp = sl.tryOptimisticRead();
            try {
                retryHoldingLock:
                for (; ; stamp = sl.writeLock()) {
                    if (stamp == 0L) continue retryHoldingLock;
                    double currentX = x;
                    double currentY = y;
                    if (!sl.validate(stamp)) continue retryHoldingLock;
                    // possibly racy reads  
                    if (currentX != 0.0 || currentY != 0.0) break;
                    stamp = sl.tryConvertToWriteLock(stamp);
                    if (stamp == 0L) continue retryHoldingLock;
                    // exclusive access
                    x = newX;
                    y = newY;
                    return;
                }
            } finally {
                if (StampedLock.isWriteLockStamp(stamp)) sl.unlockWrite(stamp);
            }
        }      // upgrade read lock to write lock    

        void moveIfAtOrigin2(double newX, double newY) {
            long stamp = sl.readLock();
            try {
                while (x == 0.0 && y == 0.0) {
                    long ws = sl.tryConvertToWriteLock(stamp);
                    if (ws != 0L) {
                        stamp = ws;
                        x = newX;
                        y = newY;
                        break;
                    } else {
                        sl.unlockRead(stamp);
                        stamp = sl.writeLock();
                    }
                }
            } finally {
                sl.unlock(stamp);
            }
        }
    }

3,源码解读

1,状态State值对应Mask

你可能感兴趣的:(java,开发语言)