前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试被问到 读写锁,慌了!

面试被问到 读写锁,慌了!

作者头像
田维常
发布2023-08-31 11:55:35
1370
发布2023-08-31 11:55:35
举报
文章被收录于专栏:Java后端技术栈cwnait

你好,我是田哥

尽管不是面试黄金时段,但还是有部分朋友获得面试机会。另外,在面试中,大部分朋友都怕被问并发编程相关技术,主要原因有两个:

1:根本没有学过,或者是没有系统学习过。

2:项目中压根儿没用过(面试问你了,等你入职才发现其实也不用

关于并发编程,我画了一张图,这张图是将并发编程知识串联起来,全网唯一

需要高清图请联系我

昨天,一位朋友面试中被问到一个比较冷门的并发编程知识;

ReadWriteLock 和 StampedLock 的区别。

实话说,这个问题确实很冷门,我面试辅导过那么多人,都没有被问过。这类问题,单靠普通八股文确实很难应对,需要系统学习过。面试辅导基本上都是速成,速成基本上都是靠高频题、面试技巧等方式来搞定。对于这类冷门知识点,只能按照我给的回答思路和套路去面对。

如果需要模拟面试、面试辅导、技术辅导的朋友,可以私信找我,也可以参考文章看具体详情全程面试辅导,保驾护航!

好了,扯远了,咱们开始今天的主题。

在多线程编程中,对于共享资源的访问控制是一个非常重要的问题。在并发环境下,多个线程同时访问共享资源可能会导致数据不一致的问题,因此需要一种机制来保证数据的一致性和并发性。

Java提供了多种机制来实现并发控制,其中 ReadWriteLock 和 StampedLock 是两个常用的锁类。本文将分别介绍这两个类的特性、使用场景以及示例代码。

ReadWriteLock

ReadWriteLock 是Java提供的一个接口,全类名:java.util.concurrent.locks.ReentrantLock。它允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这种机制可以提高读取操作的并发性,但写入操作需要独占资源。

特性

  • 多个线程可以同时获取读锁,但只有一个线程可以获取写锁。
  • 当一个线程持有写锁时,其他线程无法获取读锁和写锁,读写互斥。
  • 当一个线程持有读锁时,其他线程可以同时获取读锁,读读共享。

使用场景

ReadWriteLock 适用于读多写少的场景,例如缓存系统、数据库连接池等。在这些场景中,读取操作占据大部分时间,而写入操作较少。

示例代码

下面是一个使用 ReadWriteLock 的示例,实现了一个简单的缓存系统:

代码语言:javascript
复制
public class Cache {
    private Map<String, Object> data = new HashMap<>();
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public Object get(String key) {
        lock.readLock().lock();
        try {
            return data.get(key);
        } finally {
            lock.readLock().unlock();
        }
    }

    public void put(String key, Object value) {
        lock.writeLock().lock();
        try {
            data.put(key, value);
        } finally {
            lock.writeLock().unlock();
        }
    }
}

在上述示例中,Cache 类使用 ReadWriteLock 来实现对 data 的并发访问控制。get 方法获取读锁并读取数据,put 方法获取写锁并写入数据。

StampedLock

StampedLock 是Java 8 中引入的一种新的锁机制,全类名:java.util.concurrent.locks.StampedLock,它提供了一种乐观读的机制,可以进一步提升读取操作的并发性能。

特性

  • 与 ReadWriteLock 类似,StampedLock 也支持多个线程同时获取读锁,但只允许一个线程获取写锁。
  • 与 ReadWriteLock 不同的是,StampedLock 还提供了一个乐观读锁(Optimistic Read Lock),即不阻塞其他线程的写操作,但在读取完成后需要验证数据的一致性。

使用场景

StampedLock 适用于读远远大于写的场景,并且对数据的一致性要求不高,例如统计数据、监控系统等。

示例代码

下面是一个使用 StampedLock 的示例,实现了一个计数器:

代码语言:javascript
复制

public class Counter {
    private int count = 0;
    private StampedLock lock = new StampedLock();

    public int getCount() {
        long stamp = lock.tryOptimisticRead();
        int value = count;
        if (!lock.validate(stamp)) {
            stamp = lock.readLock();
            try {
                value = count;
            } finally {
                lock.unlockRead(stamp);
            }
        }
        return value;
    }

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

在上述示例中,Counter 类使用 StampedLock 来实现对计数器的并发访问控制。getCount 方法首先尝试获取乐观读锁,并读取计数器的值,然后通过 validate 方法验证数据的一致性。如果验证失败,则获取悲观读锁,并重新读取计数器的值。increment 方法获取写锁,并对计数器进行递增操作。

总结

ReadWriteLockStampedLock 都是Java中用于并发控制的重要机制。

  • ReadWriteLock 适用于读多写少的场景;
  • StampedLock 则适用于读远远大于写的场景,并且对数据的一致性要求不高;

在实际应用中,我们需要根据具体场景来选择合适的锁机制。通过合理使用这些锁机制,我们可以提高并发程序的性能和可靠性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端技术全栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ReadWriteLock
    • 特性
      • 使用场景
        • 示例代码
        • StampedLock
          • 特性
            • 使用场景
              • 示例代码
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档