美文网首页
StampedLock悲观锁乐观锁

StampedLock悲观锁乐观锁

作者: 刘彦青 | 来源:发表于2019-10-17 00:00 被阅读0次

    StampedLock java1.8提供的, 性能比ReadWriteLock好.

    语法

        final StampedLock sl = new StampedLock();
     
        /**
        * 悲观读锁
        * 与ReadWriteLock的读锁相似
        * 允许多个线程进行读操作
        * 与写锁互斥
        **/
        //获取悲观锁
        long stamp = sl.readLock();
        try {
          //。。。。
        }finally {
          sl.unlockRead(stamp);
        }
    
    
        /**
        * 写锁
        * 与ReadWriteLock的写锁相似
        * 只允许一个线程进行写操作
        * 与读锁互斥
        **/
         //获取写锁
        long stamp1 = sl.writeLock();
        try{
            //。。。
        }finally {
            //释放写锁
            sl.unlockWrite(stamp1);
        }
    
    
        /**
        * 乐观读锁升级为悲观读
        * 锁的严苛程度变强叫做升级,反之叫做降级
        **/
        //获取乐观锁
        long stamp = sl.tryOptimisticRead();
         //判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false
        if (!sl.validate(stamp)){
            //升级为悲观锁
            stamp = sl.readLock();
            try{
                //。。。
            }finally {
                //释放悲观读锁
                sl.unlockRead(stamp);
            }
    
    

    StampedLock提供的乐观读,是允许一个线程获取写锁的,也就是说不是所有的写操作都是被阻塞的。

    乐观读和乐观锁是不一样的,乐观读这个操作是无锁的,乐观读认为读的时候不会有写的操作。

    示例

    import java.util.concurrent.locks.StampedLock;
    
    /**
     * 悲观锁乐观锁
     **/
    public class Point {
        private int x;
        private int y;
        final StampedLock sl = new StampedLock();
    
        //计算到原点的距离
        int distanceFromOrigin() throws  Exception{
            //乐观锁
            long stamp = sl.tryOptimisticRead();
            //读入局部变量,读的过程数据可能被修改
            int curX = x;
            int curY = y;
    
            //判断执行读操作期间,是否存在写操作,如果存在则sl.validate返回false
            if (!sl.validate(stamp)){
                //升级为悲观锁
                stamp = sl.readLock();
                try{
                    curX = x;
                    curY = y;
                }finally {
                    //释放悲观读锁
                    sl.unlockRead(stamp);
                }
            }
    
            return (int)Math.sqrt(curX*curX + curY*curY);
        }
    }
    

    特征

    1. StampedLock支持三种模式: 写锁、悲观读和乐观读。
    2. 允许多 个线程同时获取乐观锁和悲观读锁。
    3. 只允许一个线程获取写锁,写锁和悲观读锁是互斥的。
    4. 使用StampedLock一定不要调用中断操作,如果需要支持中断功能,一定使用可中断的悲观读锁 readLockInterruptibly()和写锁writeLockInterruptibly()。
    5. StampedLock里的写锁和悲观读锁加锁成功之后,都会返回一个stamp;然后解锁的时候,需要传入这个 stamp。
    6. StampedLock不支持重入(ReadWriteLock支持)。
    7. StampedLock的悲观读锁、写锁都不支持条件变量。
    8. StampedLock支持锁的降级(通过tryConvertToReadLock()方法实现)和升级(通过 tryConvertToWriteLock()方法实现),但是建议你要慎重使用。

    数据库中的乐观锁

    1. 在表中添加一个数值型版本号字段version。
    2. 每次更新表时都将version字段加1。
    3. 修改数据时使用主键和version作为修改条件,version一致则会修改成功。
    4. 如果修改失败,通过主键查询获取最新数据再执行修改。

    **** 码字不易如果对你有帮助请给个关注****

    **** 爱技术爱生活 QQ群: 894109590****

    相关文章

      网友评论

          本文标题:StampedLock悲观锁乐观锁

          本文链接:https://www.haomeiwen.com/subject/ljdbuctx.html