原创

StampedLock

温馨提示:
本文最后更新于 2025年06月09日,已超过 368 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

实现 普通 读写互斥 功能



import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.StampedLock;

public class test {
    static int number = 1;
    static StampedLock stampedLock = new StampedLock();

    public void write() {
        long stamp = stampedLock.writeLock();
        System.out.println(Thread.currentThread().getName() + "writeLock 准备修改");
        try {
            number = number + 13;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
        System.out.println(Thread.currentThread().getName() + "writeLock 修改完成");
    }

    // 悲观读
    public void read() {
        long stamp = stampedLock.readLock();
        System.out.println(Thread.currentThread().getName() + "进入 ,4秒后继续");
        for (int i = 0; i < 4; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + "正在读取中……");
        }

        try {
            int result = number;
            System.out.println(Thread.currentThread().getName() + "成员变量值 result " + result);
            System.out.println("写锁没介入");
        } finally {
            stampedLock.unlockRead(stamp);
        }

    }

    public static void main(String[] args) {
        test source = new test();
        new Thread(() -> {
            source.read();
        }, "read").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "进入 ");
            source.write();
        }, "write").start();
    }
}

 乐观读模式 


import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.StampedLock;

public class test {
    static int number = 17;
    static StampedLock stampedLock = new StampedLock();

    public void write() {
        long stamp = stampedLock.writeLock();
        System.out.println(Thread.currentThread().getName() + "writeLock 准备修改");
        try {
            number = number + 13;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
        System.out.println(Thread.currentThread().getName() + "writeLock 修改完成" + number);
    }

    // 悲观读
    public void read() {
        long stamp = stampedLock.readLock();
        System.out.println(Thread.currentThread().getName() + "进入 ,4秒后继续");
        for (int i = 0; i < 4; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + "正在读取中……");
        }

        try {
            int result = number;
            System.out.println(Thread.currentThread().getName() + "成员变量值 result " + result);
            System.out.println("写锁没介入");
        } finally {
            stampedLock.unlockRead(stamp);
        }

    }

    // 乐观读  读的过程允许写锁介入
    public void tryOptimisticRead() {
        long optimisticRead = stampedLock.tryOptimisticRead();
        int result = number;

        System.out.println(Thread.currentThread().getName() + "进入 ,4秒前" + stampedLock.validate(optimisticRead));
        for (int i = 0; i < 4; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + "正在读取中……" + i + "秒 戳记" + stampedLock.validate(optimisticRead));
            if (!stampedLock.validate(optimisticRead)) {
                System.out.println("被修改过 ……");
                optimisticRead = stampedLock.readLock();
                try {
                    System.out.println("乐观 变 悲观 ");
                    result = number;
                    System.out.println(Thread.currentThread().getName() + "乐观 变 悲观  result " + result);
                } finally {
                    stampedLock.unlockRead(optimisticRead);
                }

                System.out.println(Thread.currentThread().getName() + "最终结果 result " + result);
            }

        }

    }

    public static void main(String[] args) {
    
        test source = new test();
        new Thread(() -> {
            source.tryOptimisticRead();
        }, "read").start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "进入 ");
            source.write();
        }, "write").start();

    }
}

 缺点

  • SrampedLock 不支持重入
  • StampedLock 的悲观锁和乐观锁都不支持条件变量
  • 使用StampedLock一定不要调用中断操作,不要调用 interrupt()方法




正文到此结束