详解 ReadWriteLock 和 StampedLock的区别和联系

一、什么是ReadWriteLock

ReadWriteLock是Java中的一种锁机制,它允许多个线程同时对某个共享资源进行读操作,但在写操作时必须独占该资源。相比于传统的同步锁(synchronized),ReadWriteLock提供了更细粒度的控制,可以大大提高并发性能。

在ReadWriteLock中,有两种锁:读锁和写锁。读锁可以被多个线程同时持有,但写锁只能被一个线程独占。当一个线程获得写锁时,其他线程不能获得读锁或者写锁,只能等待写锁释放。在读操作比写操作频繁的情况下,使用ReadWriteLock可以提高系统的并发性能。

以下是一个简单的Java示例代码,使用ReadWriteLock实现对共享资源的读写访问控制:

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class SharedResource {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private String data;

    public void writeData(String newData) {
        lock.writeLock().lock();
        try {
            // 写操作
            data = newData;
        } finally {
            lock.writeLock().unlock();
        }
    }

    public String readData() {
        lock.readLock().lock();
        try {
            // 读操作
            return data;
        } finally {
            lock.readLock().unlock();
        }
    }
}

在上面的代码中,我们通过添加ReadWriteLock实例来控制对data变量的并发访问。在writeData方法中,我们获取了写锁,执行写操作,并释放锁。在readData方法中,我们获取了读锁,执行读操作,并释放锁。这样,在多线程环境下,对于同一个SharedResource实例,任何时候只有一个线程可以写入data,但同时可以有多个线程同时读取data。这样就保证了线程安全性和并发性。

二、什么是StampedLock

StampedLock是Java 8中引入的一种新型锁,它提供了三种模式:读、写和乐观读。与ReentrantReadWriteLock相比,StampedLock使用更加灵活和高效,并且可以防止ABA问题的发生。

StampedLock的使用类似于ReadWriteLock,但有一些区别。StampedLock不支持可重入性,因此在同一个线程中对StampedLock进行多次加锁会导致死锁。此外,在使用StampedLock时需要注意控制锁的版本号,以避免ABA问题。

下面是一个使用StampedLock的示例代码:

import java.util.concurrent.locks.StampedLock;

public class StampedLockExample {
    private final StampedLock lock = new StampedLock();
    private double x;
    private double y;

    public void move(double deltaX, double deltaY) {
        long stamp = lock.writeLock();
        try {
            x += deltaX;
            y += deltaY;
        } finally {
            lock.unlockWrite(stamp);
        }
    }

    public double distanceFromOrigin() {
        long stamp = lock.tryOptimisticRead();
        double currentX = x;
        double currentY = y;
        if (lock.validate(stamp)) {
            return Math.sqrt(currentX * currentX + currentY * currentY);
        } else {
            stamp = lock.readLock();
            try {
                currentX = x;
                currentY = y;
                return Math.sqrt(currentX * currentX + currentY * currentY);
            } finally {
                lock.unlockRead(stamp);
            }
        }
    }
}

在这个示例中,StampedLockExample类有两个私有成员变量xy,它们表示一个二维平面上的点。move()方法用于更新这个点的位置,在方法内部使用writeLock()获取写锁,以确保线程安全。distanceFromOrigin()方法用于计算该点与原点之间的距离,并且使用了乐观读取模式来提高性能。如果验证成功,就直接返回计算结果;否则,需要使用readLock()获取读锁并重新计算。最后记得释放锁。

三、ReadWriteLock 和 StampedLock的区别和联系

ReadWriteLock和StampedLock都是Java中用于多线程读写操作的锁机制。

区别:

  1. 功能不同:ReadWriteLock提供了一种典型的读写锁定,允许多个线程同时读取共享数据,但只允许一个线程写入共享数据,而StampedLock除了支持读和写的锁定模式之外,还支持另外一种乐观锁模式,这种模式下所有的操作都不会阻塞线程。

  2. 性能不同:StampedLock比ReadWriteLock更轻量级,在低并发访问下性能更好,但在高并发状态下性能不如ReadWriteLock。

联系:

  1. 都是用于多线程读写操作的锁机制。

  2. 两者都支持可重入性和公平性。

  3. 都可以使用tryLock()方法尝试获取锁,如果获取不到也不会阻塞线程。

  4. 都是JDK中提供的线程安全的锁机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

揣晓丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值