亲宝软件园·资讯

展开

Java  StampedLock锁

派大大大星  人气:0

StampedLock:

StampedLock是并发包里面JDK8版本新增的一个锁,该锁提供了三种模式的读写控制,当调用获取锁的系列函数时,会返回一个long 型的变量,我们称之为戳记(stamp),这个戳记代表了锁的状态。其中try 系列获取锁的函数,当获取锁失败后会返回为0的stamp值。当调用释放锁和转换锁的方法时需要传入获取锁时返回的stamp值。

StampedLock提供的三种读写模式的锁分别如下:

StampedLock还支持这三种锁一定条件下进行相互转换。例如long tryConvertToWriteLock(long stamp)期望把stamp 标示的锁升级为写锁,

这个函数会在下面几种情况下返回一个有效的stamp(也就是晋升写锁成功):

另外,StampedLock 的读写锁都是不可重入锁,所以在获取锁后释放锁前不应该再调用会获取锁的操作,以避免造成调用线程被阻塞。当多个线程同时尝试获取读锁和写锁时,谁先获取锁没有一定的规则,完全都是尽力而为,是随机的。并且该锁不是直接实现 Lock 或 ReadWriteLock 接口,而是其在内部自己维护了一个双向阻塞队列。

下面通姑JDK8里面提供的一个管理二维点的例子来理解以上介绍的概念。

package LockSupportTest;

import com.sun.org.apache.bcel.internal.generic.BREAKPOINT;

import java.util.concurrent.locks.StampedLock;

public class Point_Class {
    private double x,y;
    private final StampedLock sl = new StampedLock();
    
    void move(double deltaX, double deltaY) {
        long stamp = sl.writeLock();
        try {
            x += deltaX;
            y += deltaY;
        } finally {
            sl.unlockWrite(stamp);
        }
    }
    
    double distanceFromOrin() {
        long stamp = sl.tryOptimisticRead();
        double currentX = x, currentY = y;
        if (!sl.validate(stamp)) {
            stamp = sl.readLock();
            try {
                currentX = x;
                currentY = y;
            } finally {
                sl.unlockRead(stamp);
            }
        }
        return Math.sqrt(currentX*currentX + currentY*currentY);
    }
    
    void moveIfAtOrigin(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);
                }
            }
}

在如上代码中,Point类里面有两个成员变量(x,y)用来表示一个点的二维坐标,和三个操作坐标变量的方法。另外实例化了一个StampedLock对象用来保证操作的原子性。

加载全部内容

相关教程
猜你喜欢
用户评论