Java面试篇基础部分-Java语言中的锁有哪些?

  Java中的锁主要是用于保障并发线程场景下的数据一致性问题。在多线程编程中为了保证数据一致性,通常需要在使用对象或者方法之前进行加锁操作。也就是说要保证在同一时间内只能由一个线程来对对象进行修改,从而保证了数据一致性,保证了数据安全问题。

  锁从使用角度上来说可以分为乐观锁和悲观锁,从获取资源的公平性角度上来讲可以分为公平锁和非公平锁,从是否共享资源的角度上来讲可以分为共享锁和独占锁,从锁的状态角度可以分为偏向锁、轻量级锁和重量级锁。

乐观锁

  乐观锁采用了乐观的思想来处理数据,每次读取数据的时候都会认为没有其他人对数据进行修改,所以也就不会上锁,但是在更新的时候会判断是否有人更新过该数据,想要解决这个问题,通常采用的方式就是在写数据的时候先读取出当前的版本号,然后加锁的方式,具体的过程如下

  比较当前版本号与上次的版本号,如果版本号一致,就说明没有更新过,此次就是最新的数据,如果版本号不一致,则进行重复的读写进行比较。

  Java中的乐观锁大部分的场景下是使用CAS(Compare And Swap,比较交换)来实现的,CAS是一种原子更新操作 ,在对数据操作之前首先会比较当前值与传入的值是否一样,如果一样则更新,否则不执行更新操作 ,直接返回失败状态。

悲观锁

  悲观锁采用悲观思想处理数据,也就是说假设在每次读取数据的时候都会认为其他人在修改数据,所以每次在读写数据的时候都会上锁,这样别人想写这个数据的时候就会直接进入到阻塞状态、等待获取到锁。

  Java中的悲观锁大部分的是基于AQS(Abstract Queued Synchronized,抽象的队列同步器)架构来实现。AQS定义了一套多线程访问共享资源的同步架构,许多同步类的实现都依赖于它,例如 Synchroinzed、ReentrantLock、Semaphore、CountDownLatch等等。该框架下的锁首先会尝试一CAS的方式去获取锁,如果获取不到锁,则转换为悲观锁,例如RetreenLock。

自旋锁

  自旋锁:如果持有锁的线程能在很短的时间内释放锁资源,那么这些等待竞争锁的线程就不需要做内核态与用户态之间的切换进入到阻塞、挂起状态,只需要等待一段时间就可以了,也就是自旋。在等待持有锁的线程释放锁之后立即获取到锁,这样就避免了用户线程在内核状态的切换上导致锁的时间消耗。

  线程在自旋时会占用CPU,在线程长时间自旋无法获取到锁,就会导致CPU的浪费,甚至有时线程永远无法获取锁导致CPU资源永远被占用。这个时候就需要设置这个自旋锁的最大自旋时间,有了这个时间以后,如果在这个时间之内没有获取到锁,线程就会退出自旋模式并且释放所持有的锁。

优点

  1、自旋锁在一定程度上减少了CPU上下文之间的切换,可以大幅度的提升锁占用时间短,锁竞争不激烈的代码块的性能。在整个的过程中,CPU耗时是明显少于线程阻塞、挂起、唤醒两次CPU上下文所用的时间。

缺点

  1、如果持有锁的线程占用较长的时间或者获取锁的竞争过于激烈的时候,线程在自旋的过程中会长时间的获取不到资源,导致CPU资源的浪费。所以在有些复杂系统中使用自旋锁的时候要慎重。

  应该如何解决自旋锁的执行时间问题呢?如果自旋锁的执行时间太长了,就会有大量的线程处于自旋状态,占用CPU资源,造成系统资源浪费。所以执行时间的长短设置直接会影响到系统的性能

  JDK在不同的版本中采用了不同的周期,JDK1.5固定DE时间,JDK1.6引入了适应性的自旋锁。适应性的自旋锁自旋时间不是固定的,而是通过上次的时间进行计算得到。可以基本上确定一个线程上下文切换的最佳时间。

相关推荐
小bo波3 小时前
Java Swing 图形用户界面实验 —— 从算术练习到游戏开发的完整实践
java·课程设计·gui·游戏开发·扫雷·swing
咖啡八杯5 小时前
GoF设计模式——备忘录模式
java·后端·spring·设计模式
HjhIron8 小时前
面试常客:字符串算法从入门到进阶
算法·面试
大志说编程9 小时前
Agent面试真题06: 十分钟带你快速掌握Agent记忆管理高频面试题(附详细答案)
后端·面试·ai编程
众人皆醒我独醉9 小时前
Kubernetes 为什么不直接调度容器?非要套一层 Pod
面试
亮亮不想说话9588810 小时前
iOS底层探索 -- GCD分析
面试
程序员小假11 小时前
从问题到答案:RAG系统完整处理流程与核心机制深度拆解
后端·面试·agent
SamDeepThinking15 小时前
裁掉那个差程序员后,给你看团队里高手的代码:这个习惯,希望你有
java·后端·程序员
朕瞧着你甚好16 小时前
技术雷达 & Java 集成评估报告 — Apache Tika 3.3.1
java·ai编程
沉默王二16 小时前
阿里一面,我霸气反问:你说你们在做Agent项目,说说langchain、muti-agent、a2a这些你们都是怎么做的?面试官一直在擦汗。。
面试·agent·ai编程