首页常见问题正文

请谈谈ReadWriteLock和StampedLock

更新时间:2023-03-14 来源:黑马程序员 浏览量:

IT培训班

  ReadWriteLock和StampedLock都是Java中的锁实现,它们都可以用于解决多线程并发访问共享资源的问题。ReadWriteLock主要是用于读写分离场景,StampedLock则是为了更高效地支持乐观读模式而设计的。

  ReadWriteLock是Java中一个比较常见的锁实现,它包含一个读锁和一个写锁。在多个线程读取共享资源时,可以同时获取读锁;当某个线程想要修改共享资源时,需要获取写锁,此时其他线程将被阻塞,直到写锁被释放。

  StampedLock是JDK1.8中新添加的锁实现,相对于ReadWriteLock,它可以提供更高的性能。StampedLock支持三种访问模式:读、写和乐观读。在读写锁的情况下,一旦有一个写线程,所有读线程都需要等待,而StampedLock中的乐观读模式则不需要等待写锁,因为它假设并发冲突的可能性很低。

  以下是示例代码演示了如何使用ReadWriteLock和StampedLock实现线程安全的共享资源访问:

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

public class Example {
    private int count = 0;
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private StampedLock stampedLock = new StampedLock();

    public void incrementWithReadWriteLock() {
        readWriteLock.writeLock().lock();
        try {
            count++;
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    public int getCountWithReadWriteLock() {
        readWriteLock.readLock().lock();
        try {
            return count;
        } finally {
            readWriteLock.readLock().unlock();
        }
    }

    public void incrementWithStampedLock() {
        long stamp = stampedLock.writeLock();
        try {
            count++;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }

    public int getCountWithStampedLock() {
        long stamp = stampedLock.tryOptimisticRead();
        int currentCount = count;
        if (!stampedLock.validate(stamp)) {
            stamp = stampedLock.readLock();
            try {
                currentCount = count;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        return currentCount;
    }
}

  在这个示例中,Example类中有一个共享资源count,通过readWriteLock和stampedLock实现了对它的线程安全访问。其中incrementWithReadWriteLock和getCountWithReadWriteLock方法使用了ReadWriteLock,incrementWithStampedLock和getCountWithStampedLock方法使用了StampedLock。

  在incrementWithStampedLock和getCountWithStampedLock方法中,我们使用了StampedLock的乐观读模式。首先我们尝试获取一个乐观读锁,然后读取共享资源count的值。如果在乐观读的过程中没有其他线程获取写锁修改了count,那么我们就可以直接返回乐观读取的值。如果在乐观读的过程中,有其他线程获取了写锁并修改了count,那么乐观读锁就会失效,我们需要获取一个读锁,并重新读取count的值,最后释放读锁并返回当前读取到的count值。

  需要注意的是,StampedLock的乐观读模式并不适用于所有场景。如果在乐观读过程中,有较高的并发写操作,那么会导致乐观读的效率变得低下,因为每次乐观读都需要进行一次读锁的获取和释放操作。在这种情况下,使用ReadWriteLock可能更加适合。

  总的来说,ReadWriteLock和StampedLock都是Java中非常实用的锁实现,可以在多线程并发访问共享资源的情况下保证线程安全。在实际开发中,需要根据具体场景和需求来选择合适的锁实现。

1678757415555_领取课程.jpg

分享到:
在线咨询 我要报名
和我们在线交谈!