面试题之并发相关专栏二

一、什么是锁消除和锁粗化?

  • 锁消除:指虚拟机即时编译器在运行时,对一些代码上要求同步,但被检测到不可能存在共享数据竞争的锁进行消除。
  • 锁粗化:原则上,同步块的作用范围应该尽可能的小,也就是说锁的粒度要尽可能小一点。但是如果一系列的连续操作都对同一个对象反复加锁和解锁,甚至加锁操作在循环体内,频繁地进行互斥同步也会导致不必要的性能损耗,锁粗化就是增大锁的作用范围。

二、为什么说Synchronized是一个悲观锁?

Synchronized显然是悲观的,不管是否会产生竞争,任何的数据操作都必须要加锁、维护锁的计数器和检查是否有被阻塞的线程需要被唤醒等操作。

三、乐观锁的实现原理是什么?什么是CAS,它有什么特性?

随着硬件指令集的发展,我们可以使用基于冲突检测的乐观并发策略,先进行操作,如果没有其他线程征用数据,那操作就成功了;如果共享数据有征用,产生了冲突,那就再进行其他的补偿措施,这种乐观的并发策略的许多实现不需要线程挂起,所以被称为非阻塞同步。

乐观锁的核心就是CAS算法(CompareAndSwap算法),指的是比较且交换,它涉及到三个操作数: 内存值、预估值、新值。当且仅当预估值和内存值相同时才将内存值更新为新值。这样处理的逻辑是,首先检查某块内存的值是否跟之前我读取时的一样,如不一样表示期间此内存值已经被别的线程修改过,舍弃本次操作,否则说明期间没有其他线程对此内存值操作,可以把新值设置给此块内存。CAS具有原子性,它的原子性由CPU硬件指令实现保证,即使用JNI调用Native本地方法调用由C++编写的硬件级别指令,JDK中提供了Unsafe类执行这些操作。

四、乐观锁一定是好的吗?

乐观锁避免了悲观锁独占对象德现象,同时提高了并发性能,但它也有缺点。

  • 乐观锁只能保证一个共享变量的原子操作,如果多一个或几个变量,乐观锁就显得力不从心了,但互斥锁能轻松解决在该问题,不管对象数量多少和对象颗粒度大小;
  • 长时间自旋可能导致开销很大,加入CAS长时间不成功而一直自旋,会给CPU带来很大的开销;
  • ABA问题,CAS的核心思想是通过对比内存值和预估值是否一样而判断内存值是否有被改过,这个判断逻辑并不严谨,ABA问题,就是说一个线程把数据A变为了B,然后又重新变成了A。此时另外一个线程读取的时候,发现A没有变化,就误以为是原来的那个A,则CAS认为此内存值并没有发生改变,但实际上是有被其他线程改过的。解决的思路就是引入版本号, 每次变量更新都把版本号加1;

五、请说出 Synchronized和ReentrantLock的异同?

ReentrantLock的功能比ReentrantLock强大,主要的不同点如下图所示:

发布了250 篇原创文章 · 获赞 112 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/Weixiaohuai/article/details/105331896