Sychronized和ReentrantLock锁 面试题

Sychronized和ReentrantLock锁 面试题

  • 前言
  • 1、Java死锁如何避免?
  • 2、公平锁和⾮公平锁的底层实现?
  • 3、ReentrantLock中tryLock()和lock()⽅法的区别?
  • 4、Sychronized的偏向锁、轻量级锁、重量级锁?
  • 5、谈谈你对AQS的理解,AQS如何实现可重⼊锁?
  • 6、AQS锁的类别?
  • 7、CountDownLatch和Semaphore的区别和底层原理?
  • 8、ReentrantLock底层原理?
  • 9、Sychronized和ReentrantLock的区别?
  • 10、Synchronized 偏向锁有个开关,如果默认开启有什么缺点?
  • 11、CAS与传统synchronized区别
  • 12、CAS是不是操作系统执行的?
  • 13、说一下CAS怎么用的,会有哪些问题?
  • 14、cas自增 和 Synchronized 自增 谁快?
  • 15、Synchronized 和 ReentracLock 哪个快,为啥?
  • 16、怎么检测一个线程是否拥有锁?
  • 17、事务未提交而锁提前释放了?
  • 18、AtomicInteger计数器自增到一万以后,怎么归零?
  • GIT
  • 19、什么是git?
  • 20、列举工作中常用的git命令:
  • 总结


前言

最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。

如果对老铁有帮助,帮忙免费点个赞,谢谢你的发财手!

1、Java死锁如何避免?

造成死锁的4个必要条件:

  • 1.⼀个线程每次只能占有⼀个资源;
  • 2.⼀个线程在阻塞等待某个资源时,不释放已占有资源;
  • 3.⼀个线程已占有的资源,在未使⽤完之前,不能被强⾏剥夺;
  • 4.多个线程形成循环等待的关系。
    如果要避免死锁,只需要其中某⼀个条件不满⾜即可。
    在开发过程中:
  • 1.要注意加锁顺序,保证每个线程按同样的顺序进⾏加锁解锁;
  • 2.要注意加锁时限,可以针对锁设置⼀个超时时间;
  • 3.要注意死锁检查,这是⼀种预防机制,确保在第⼀时间发现死锁并进⾏解决。

2、公平锁和⾮公平锁的底层实现?

公平锁和⾮公平锁,它们的底层实现都会使⽤AQS来进⾏排队。
它们的区别在于:

  • 如果是公平锁,会先检查AQS队列中是否存在线程在排队,如果有线程在排队,则当前线程也进⾏排队。
  • 如果是⾮公平锁,则不会去AQS队列中检查是否有线程在排队,⽽是直接竞争锁。
    不管是公平锁还是⾮公平锁,⼀旦没竞争到锁,都会进⾏排队,当锁释放时,都是唤醒排在最前⾯的线程,所以⾮公平锁只是体现在了线程加锁阶段,而没有体现在线程唤醒阶段。
    另外,不管是公平锁还是⾮公平锁都是可重⼊的。

3、ReentrantLock中tryLock()和lock()⽅法的区别?

  • 1.tryLock()表示尝试加锁,可能加到,也可能加不到,该⽅法不会阻塞线程,如果加到锁则返回true,没有加到则返回false ;
  • 2.lock()表示阻塞加锁,线程会阻塞直到加到锁,⽅法也没有返回值。

4、Sychronized的偏向锁、轻量级锁、重量级锁?

  • 1、偏向锁:在锁对象的对象头中记录了当前获取到锁的线程ID,如果该线程⼜来获取锁,就可以直接获取到了,这就是可重入的概念;
  • 2、轻量级锁:如果有另外的线程来竞争锁,偏向锁就会升级为轻量级锁,轻量级锁的底层是通过⾃旋来实现的,并不会阻塞线程;
  • 3、重量级锁:如果⾃旋次数超过10次仍然没有获取到锁,则会升级为重量级锁,重量级锁会导致线程阻塞。
  • 4、⾃旋锁:⾃旋就是线程在获取锁的过程中,不会去阻塞线程,是线程通过CAS获取预期的⼀个标记,如果没有获取到,则继续循环获取,如果获取到了则表示获取到了锁,这个过程线程⼀直在运⾏中,消耗的CPU资源比较少,⽐较轻量。

5、谈谈你对AQS的理解,AQS如何实现可重⼊锁?

  • 1.AQS是⼀个抽象的对列同步器,在AQS中,维护了一个volatile修饰的state标识和⼀个双向链表队列(FIFO);
  • 2.这个队列就是⽤来给线程排队的,⽽state就像是⼀个红绿灯,⽤来控制线程排队或者放⾏的;
  • 3.在可重⼊锁的场景下,state就⽤来表示加锁的次数,0标识⽆锁,每加⼀次锁,state就加1,释放锁state就减1。

6、AQS锁的类别?

AQS分为“排他锁”和“共享锁”两种:

  • 1.排他锁:是指在同一时刻只能有一个线程去占有锁,其他线程既不可以读,也不可以写,比如ReentrantLock;
  • 2.共享锁:是指在同一时刻可以有多个线程去占有锁,其他线程可以读,但不可以写,比如CountDownLatch计数器和Semaphore信号量;
    另外AQS也支持同时实现独占和共享两种方式,比如ReentrantReadWriteLock。

7、CountDownLatch和Semaphore的区别和底层原理?

底层都是通过AQS实现的。

  • CountDownLatch计数器:比如某个任务分为N个子线程并发去执行,state 也初始化为N;每个子线程执行完后调用countDown方法,state会减1,当所有子线程都执行完后,即state=0 ,然后会依次去唤醒AQS中排队的线程。
  • Semaphore信号量:我们常常用它来控制对有限资源的访问,每次使用资源前,先申请一个信号量,如果信号量不够,就会阻塞等待,并通过AQS来排队,当某个线程释放资源后,就释放一个信号量,然后会依次去唤醒AQS中排队的线程。

8、ReentrantLock底层原理?

底层是通过AQS实现的,state 初始化为 0,表示无锁状态;A 线程调用lock(加锁) 时,会将 state加 1 ,直到 A 线程调用 unlock(释放锁) 到 state=0为止,其它线程才有机会获取该锁。当然,释放锁之前,A 线程自己是可以重复获取该锁的,state 会累加,这就是可重入的概念。但要注意,加了多少次就锁要释放多少次,这样才能保证state恢复到0。

9、Sychronized和ReentrantLock的区别?

  • 1、Sychronized是⼀个关键字,ReentrantLock是⼀个类;
  • 2、Sychronized会自动的加锁和释放锁,ReentrantLock需要手动加锁和释放锁;
  • 3、Sychronized是非公平锁,ReentrantLock可以选择公平锁或非公平锁(默认);
  • 4、Sychronized是JVM层⾯的锁,ReentrantLock是API层⾯的锁。
  • 5、ReentrantLock有个tryLock()方法,尝试抢占锁,不会造成阻塞,加到锁返回true。
    理解第4点:Sychronized锁的是对象,锁信息保存在JVM对象头中,ReentrantLock是通过AQS中一个volatile修饰的state 来标识锁的状态。

10、Synchronized 偏向锁有个开关,如果默认开启有什么缺点?

JDK15默认关闭偏向锁优化,如果要开启可以使用XX:+UseBiasedLocking,但使用偏向锁相关的参数都会触发deprecate警告。
原因:在现在的jdk中,偏向锁加锁时 带来的性能提升 从整体上看并没有过多的收益,但撤销锁的成本过高,需要在一个安全点停止拥有锁的线程,使其变成无锁状态。

11、CAS与传统synchronized区别

CAS工作原理是基于乐观锁且操作是原子性的,与synchronized的悲观锁(底层需要调用操作系统的mutex锁)相比,效率也会相对高一些。

12、CAS是不是操作系统执行的?

不是,CAS是主要是通过处理器的指令来保证原子性的 。

13、说一下CAS怎么用的,会有哪些问题?

CAS就是我们所说的比较和交换,是采用的乐观锁技术,来实现线程安全的问题。
CAS有三个属性:旧值(A)、新值(B)、内存对象(V);
CAS原理就是对V进行赋值时,先判断原来的值是否为A,如果为A,就把新值B赋值到V,如果原来的值不是A(代表V的值放生了变化),那么会通过循环再走CAS流程,直到能够把新值B赋值成功(会给CPU带来很大的开销)。
CAS会有ABA的问题,可以通过加版本号,更新的时候时候不仅比较值,还比较版本号。

14、cas自增 和 Synchronized 自增 谁快?

  • 1、在线程数较少的时候,CAS实现比较快,性能优于synchronized,因为synchronized是悲观锁,存在锁竞争,会造成阻塞。
  • 2、当线程数大于一定数量的时候,CAS性能就不如synchronized了,因为多个线程在循环调用CAS接口,虽然不会让其他线程阻塞,但是这个时候竞争激烈,会导致CPU到达100%,同时会消耗更多时间。

15、Synchronized 和 ReentracLock 哪个快,为啥?

Synchronized 底层实现由JVM保证:在JVM运行过程中,可能出现偏向锁,轻量级锁,重量级锁。

  • 偏向锁:当线程第一次获取到锁的时候,将对象头中的 mark word 中的偏向锁线程的标识设为自己的id,当有其他线程竞争锁的时候,发现偏向锁线程的标识并不是自己,会进行一次 CAS替换,如果不成功,就会将锁升级为轻量级锁(消耗极少);
  • 轻量级锁:当前线程会将对象头中的 mark Word 复制到自己的栈空间中,然后通过自旋来获取锁,自旋10次还是获取锁失败,说明当前锁存在竞争,会将对象头的锁标识改为重量级指针,锁会膨胀为重量级锁(消耗:复制和自旋);
  • 重量级锁:需要操作系统实现线程之间的切换,这就需要从用户态转换到内核态,这个成本非常高,状态之间的转换需要相对比较长的时间。
  • ReentrantLock 底层是基于 AQS 实现:AQS 内部维护了一个volatile修饰的state标识以及⼀个双向链表队列(FIFO),volatile 消耗小于 Synchronized 。
    因此性能比较:偏向锁 > 轻量级锁 > ReentrantLock > Synchronized。

16、怎么检测一个线程是否拥有锁?

在 java.lang.Thread 中有一个 holdsLock()方法,拥有锁会返回 true 。

17、事务未提交而锁提前释放了?

高并发情况下,数据库事务未提交,但是锁已经释放。

  • 1、把整个事务单独封装成一个方法, 放在锁的工作范围之内;
  • 2、手动提交事务,因为事务是方法结束后才提交,我们可以手动提交事务;
  • 3、采用的Redisson可重入锁,提供watchdog机制,在锁释放前默认每10s重置锁失效时间为30s。

18、AtomicInteger计数器自增到一万以后,怎么归零?

volatile仅仅保证变量在线程间保持可见性,却依然不能保证非原子性的操作,还是用AtomicInteger类。
使用AtomicInteger.set(0)或.getAndSet(0)。

GIT

19、什么是git?

Git是一款开源的分布式版本控制系统。

20、列举工作中常用的git命令:

  • 将项目下载至本地:git clone http://xxx.git;
  • 提交文件:git commit -m “修复bug”;
  • 多次提交合成一次提交:git rebase -i HEAD~n;
  • 推送代码:git push origin dev;
  • 拉取并合并代码:git pull origin dev 等价于 git fetch origin dev + git merge origin/dev;
  • 查看历史记录:git log ;
  • 撤回(回退)版本:git revert(reset --hard) 提交id;
  • 创建并切换分支:git checkout -b dev 等价于git branch dev + git checkout dev;
  • 查看本地(远程/所有)分支:git branch(-r/-a);
  • 备份(恢复)当前工作区的内容:git stash(pop)

总结

都已经看到这里啦,赶紧收藏起来,祝您工作顺心,生活愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/722461.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL技巧笔记(一):连续3人的连号问题—— LeetCode601.体育馆的人流量

SQL 技巧笔记 前言:我发现大数据招聘岗位上的应聘流程都是需要先进行笔试,其中占比很大的部分是SQL题目,经过一段时间的学习之后,今天开了一个力扣年会员,我觉得我很有必要去多练习笔试题目,这些题目是有技…

代码随想录算法训练营第三十七天 | LeeCode 738. 单调递增的数字

题目链接:738. 单调递增的数字 - 力扣(LeetCode) class Solution { public:int monotoneIncreasingDigits(int N) {string strNum to_string(N);// flag用来标记赋值9从哪里开始// 设置为这个默认值,为了防止第二个for循环在fla…

Linux - 进程概念

1、冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系; 截至目前,我们所认识的计算机,都是有一个个的硬件组件组成: 输入单元:…

【JavaEE】_Spring MVC项目使用数组与集合传参

目录 1. 使用数组传参 1.2 传递单个参数 1.3 传递多个名称相同的参数 1.3.1 关于urlencode 2. 使用集合传参 1. 使用数组传参 创建一个Spring MVC项目,其中 .java文件内容如下: package com.example.demo.controller;import com.example.demo.Per…

2.Zookeeper集成springboot操作节点,事件监听,分布式锁实现

1.Springboot项目中添加zookeeper 已经对应的客户端依赖 &#xff0c;pom.xml文件如下 <!-- Zookeeper组件 --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.9.1</version…

【C++】6-8 评委打分 分数 10

6-8 评委打分 分数 10 全屏浏览 切换布局 作者 刘利 单位 惠州学院 某诗歌朗诵比赛&#xff0c;有n位评委给参赛者打分&#xff0c;计算总分时要去除最高分和对低分。 要求&#xff1a;编写名为cmax和cmin的函数分别返回最高分的和最低分元素的引用&#xff0c;带有2个形参…

leetcode面试经典算法题——1

链接&#xff1a;https://leetcode.cn/studyplan/top-interview-150/ 392. 判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串…

292.【华为OD机试】跳马问题(广度优先搜索(BFS)JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目二.解题思路三.题解代码Python题解代码JAVA题解…

分布式事务(SeataServer)

SeataServer搭建 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Servi…

JavaScript 闭包 作用域

闭包 JavaScript 中的闭包是相当重要的概念并且与作用域相关知识的指向密切相关 JavaScript 中的作用域是什么意思?闭包会在哪些场景中使用?通过定时器循环输出自增的数字通过 JS 的代码如何实现? 闭包概念一 闭包是指有权访问另外一个函数作用域中的变量的函数。 闭包…

自我对比: 通过不一致的解决视角更好地进行反思

一、写作动机&#xff1a; LLM 在自我评价时往往过于自信或随意性较大&#xff0c;提供的反馈固执或不一致&#xff0c;从而导致反思效果不佳。为了解决这个问题&#xff0c;作者提倡 "自我对比"&#xff1a; 它可以根据要求探索不同的解决角度&#xff0c;对比差异…

ChatGPT如何辅助医生改善AD患者教育的效果

特应性皮炎&#xff08;AD&#xff09;是一种常见的慢性炎症性皮肤病&#xff0c;在全球范围内造成了巨大的疾病负担。尽管在治疗方面取得了一定进展&#xff0c;但AD患者的生活质量较低&#xff0c;治疗满意度差&#xff0c;超过一半的患者认为中度至重度AD疾病控制不佳。AD的…

YOLO快速入门

Yolo简介 概述 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的目标检测算法&#xff0c;由Joseph Redmon等人开发。 YOLO算法以其高效的实时性能和准确的检测能力而闻名。自YOLO的首次提出以来&#xff0c;已经经 历了多个版本的更新和改进。以下是YOLO发展史的…

周边类-找厕所小程序源码

源码获取方式 1&#xff0c;搜一搜 万能工具箱合集 点击资料库 即可进去获取 找厕所小程序源码依赖于腾讯地图的一款源码&#xff0c;腾讯地图api免费申请&#xff0c;是一款免费又永久的不需要服务器的小程序&#xff0c;起个好名字蹭蹭蹭~ 搭建教程&#xff1a; 1、下载源码…

使用css的transition属性实现抽屉功能

需求 使用css手写一个抽屉&#xff0c;并且不能遮挡住原来的页面 效果&#xff1a;&#xff08;录的gif有点卡&#xff0c;实际情况很丝滑&#xff09; 实现代码&#xff1a; <template><div class"dashboard-container"><div class"mainBox&…

Java项目:36 springboot图书个性化推荐系统的设计与实现003

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 springboot003图书个性化推荐系统的设计与实现 管理员&#xff1a;首页、个人中心、学生管理、图书分类管理、图书信息管理、图书预约管理、退…

[element]element-ui框架下载

⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;努力输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐如果觉得文章写的不错&#xff0c;欢迎点个关注一键三连&#x1f609;有写的不好的地方也欢迎指正&#xff0c;一同进步&#x1f601;…

CSS中画一条0.5px的线

采用transform: scale()的方式&#xff0c;该方法用来定义元素的2D 缩放转换&#xff1a; transform: scale(0.5,0.5); 采用meta viewport的方式 <meta name"viewport" content"widthdevice-width, initial-scale0.5, minimum-scale0.5, maximum-scale0.5…

基于Springboot的足球俱乐部管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的足球俱乐部管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍: 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff…

【Datawhale组队学习:Sora原理与技术实战】Attention和LLM

Attention Attention 注意力&#xff0c;从两个不同的主体开始。 论文&#xff1a;https://arxiv.org/pdf/1703.03906.pdf seq2seq代码仓&#xff1a;https://github.com/google/seq2seq 计算方法&#xff1a; 加性Attention&#xff0c;如&#xff08;Bahdanau attention&…