面试官:那有没有比读写锁更快的锁呢?
小明:。。。。。。。。。。
我靠,问的这么深的吗?小明当时就蒙蔽了,因为它项目中使用比较多的就是synchronized,读写锁都很少用到,因为很少牵扯到多线程问题,这个面试让他知道了多线程的重要性。
=====================================================================
读写锁:允许多个线程同时读,但是只允许一个线程写,在线程获取到写锁的时候,其他写操作和读操作都会处于阻塞状态,读锁和写锁也是互斥的,所以在读的时候是不允许写的,那如何实现一个读写锁呢?
请参考:java并发编程之ReentrantReadWriteLock读写锁。
读写锁比传统的synchronized速度要快很多,原因就是在于读写锁支持读并发,而synchronized要求所有操作都是串行化,举个例子,我需要查询某个用户的基本信息,这些信息很少发生变化,所以我们会将这部分信息存放到缓存中,我们的查询操作为:
Created with Raphaël 2.2.0 开始 查询缓存 缓存中是否存在数据? 结束 查询数据库 添加到缓存 yes no
按照上面流程图,如果使用synchronized的时候,查询缓存都会阻塞,但是使用读写锁,查询缓存时并发的,查询数据库是阻塞的,所以,读写锁在读多写少的情况下,性能明显要优于synchronized。
人类的文明在进步,java也在进步,对知识的渴望也在不断的增加,所以我们就不断的在想这么一个问题,读写锁的读和写是互斥,那我们能不能做到读和写支持并发呢?
==============================================================================
StampedLock其实是对读写锁的一种改进,它支持在读同时进行一个写操作,也就是说,它的性能将会比读写锁更快。
更通俗的讲就是在读锁没有释放的时候是可以获取到一个写锁,获取到写锁之后,读锁阻塞,这一点和读写锁一致,唯一的区别在于读写锁不支持在没有释放读锁的时候获取写锁。
-
悲观读:与读写锁的读写类似,允许多个线程获取悲观读锁
-
写锁:与读写锁的写锁类似,写锁和悲观读是互斥的。
-
乐观读:无锁机制,类似于数据库中的乐观锁,它支持在不释放乐观读的时候是可以获取到一个写锁的,这点和读写锁不同。
我们先来看看悲观读于与写锁的基本语法
//获取悲观读
long stamp = lock.readLock();
try{
String info = mapCache.get(name);
if(null != info){
return info;
}
}finally {
//释放悲观读
lock.unlock(stamp);
}
//获取写锁
stamp = lock.writeLock();
try{
//判断一下缓存中是否被插入了数据
String info = mapCache.get(name);
if(null != info){
return info;
}
//这里是往数据库获取数据
String infoByDb = mapDb.get(name);<