面试题答案
一键面试适用场景
- 读多写少场景:当系统中对共享资源的读取操作远远多于写入操作时,读写锁能显著提升性能。因为读操作之间不会相互影响数据一致性,允许多个线程同时进行读操作,而写操作需要保证数据一致性,同一时间只允许一个线程进行写操作。例如缓存系统,大量线程频繁读取缓存数据,偶尔会有线程更新缓存。
- 数据一致性要求高的场景:对于一些对数据一致性要求严格的应用,如数据库事务处理相关的缓存。读操作需要确保读到的数据是最新的、一致的,写操作完成后,后续读操作能立刻获取到更新后的数据。读写锁可以通过写锁保证写操作的原子性,通过读锁保证读操作时数据的一致性。
举例说明
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Cache {
private final Map<String, Object> cache = new HashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public Object get(String key) {
lock.readLock().lock();
try {
return cache.get(key);
} finally {
lock.readLock().unlock();
}
}
public void put(String key, Object value) {
lock.writeLock().lock();
try {
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
}
在上述代码中,Cache
类使用了读写锁。多个线程可以同时调用get
方法读取缓存数据,因为读锁允许多个线程同时获取。而put
方法用于更新缓存数据,由于写锁的存在,同一时间只允许一个线程执行写操作,以保证数据的一致性。这样在缓存场景下,读多写少的操作模式能得到高效的实现。