Java锁常见面试题

news2024/11/24 22:44:59

图片引用自:不可不说的Java“锁”事 - 美团技术团队

1 java内存模型

java内存模型(JMM)是线程间通信的控制机制。JMM定义了主内存和线程之间抽象关系。线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。

2 锁的概念

2.1 什么是锁

在Java中的锁主要是用于保障线程在多并发的情况下数据的一致性。就是实现并发的原子性。

2.2 为什么加锁

在多线程编程中为了保证数据的一致性,我们通常需要在使用对象或者调用方法之前加锁,这时如果有其他线程也需要使用该对象或者调用该方法,则首先要获得锁,如果某个线程发现锁正在被其他线程使用,就会进入阻塞队列等待锁的释放,直到其他线程执行完成并释放锁,该线程才有机会再次获取锁并执行操作。这样做可以保障了在同一时刻只有一个线程持有该对象的锁并修改该对象,从而保障数据的安全性。

3 悲观锁 VS 乐观锁

悲观锁:悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,确保数据不会被别的线程修改,阻塞直到拿到锁。

实现方式:Java中悲观锁是通过synchronized关键字或ReentrantLock接口来实现的。

应用场景:悲观锁适合写操作多的场景,先加锁可以保证写操作时数据正确。

乐观锁:认为在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作(例如报错或者自动重试)。

实现方式:乐观锁在Java中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。相对于对于 synchronized 这种阻塞算法,CAS是非阻塞算法的一种常见实现。所以J.U.C在性能上有了很大的提升。当然,如果并发非常严重,那么会导致CAS的自旋非常严重,此时性能反倒不如直接使用悲观锁。

应用场景:乐观锁适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升,这样可以提高吞吐量。

// ------------------------- 悲观锁的调用方式 -------------------------
// synchronized
public synchronized void testMethod() {
	// 操作同步资源
}
// ReentrantLock
private ReentrantLock lock = new ReentrantLock(); // 需要保证多个线程使用的是同一个锁
public void modifyPublicResources() {
	lock.lock();
	// 操作同步资源
	lock.unlock();
}

// ------------------------- 乐观锁的调用方式 -------------------------
private AtomicInteger atomicInteger = new AtomicInteger();  // 需要保证多个线程使用的是同一个AtomicInteger
atomicInteger.incrementAndGet(); //执行自增1

3.1 synchronized VS Lock


1、synchronized是Java关键字,在JVM层面实现加锁和解锁;Lock是一个接口,在代码层面实现加锁和解锁。

2、synchronized可以用在代码块上、方法上;Lock只能写在代码里。

3、synchronized在代码执行完或出现异常时自动释放锁;Lock不会自动释放锁,需要在finally中显示释放锁。

4、synchronized会导致线程拿不到锁一直等待;Lock可以设置获取锁失败的超时时间。

5、synchronized无法得知是否获取锁成功;Lock则可以通过tryLock得知加锁是否成功。

6、synchronized锁可重入、不可中断、非公平;Lock锁可重入、可中断、可公平/不公平,并可以细分读写锁以提高效率

7、都是悲观锁

3.2 CAS

CAS全称 Compare And Swap(比较与交换),是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。java.util.concurrent包中的原子类就是通过CAS来实现了乐观锁。

CAS算法涉及到三个操作数:

  • 需要读写的内存值 V。
  • 进行比较的值 A。
  • 要写入的新值 B。

4 volatile

参考另外一篇文章:java并发编程中的四个关键字:ThreadLocal、Volatile、Synchronized和Atomic-CSDN博客

5 死锁

5.1 什么是死锁

不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁。

出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续。

如果没有外部干预,线程会一直阻塞无法往下执行,这些一直处于相互等待资源的线程就称为死锁线程。

5.2 产生死锁的四个必要条件


1.资源互斥:对所分配的资源进行排它性控制,锁在同一时刻只能被一个线程使用。

2.不可剥夺:线程已获得的资源在未使用完之前,不能被剥夺,只能等待占有者自行释放锁。

3.请求等待:当线程因请求资源而阻塞时,对已获得的资源保持不放

4.循环等待:线程之间的相互等待

5.3 避免死锁

按照死锁发生的四个条件,只需要破坏其中的任何一个,就可以解决,但是,互斥条件是没办法破坏的,因为这是互斥锁的基本约束,其他三方条件都有办法来破坏:

1、设置超时时间,超时可以退出,防止死锁

2、降低锁的使用粒度,尽量不要几个功能用同一把锁

3、可以一次性申请所有的资源,这样就不存在等待了

6 分布式锁

6.1 为什么

假设我们把代码部署到多台服务器上,还能生效吗?答案是否定的,这时分布式锁应运而生。

public synchronized void test1() {
    System.out.println("获取到锁1");
}
public void test2() {
     synchronized (Test.class) {
          System.out.println("获取到锁2");
     }
}

6.2 Redis分布式锁

图片来源于:Java分布式锁面试题_殷十娘的博客-CSDN博客

7 sleep() VS wait()


1、sleep方法没有释放锁,而wait方法释放了锁。

2、都可以暂停线程的执行。

3、wait()通常被用于线程交互/通信,sleep()通常被用于暂停执行。

4、wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll方法,sleep方法执行完成后,线程会自动苏醒。或者可以使用wait(long timeout)超时后线程会自动苏醒。

8 单例模式

加入violate可以避免重排序

class SingletonClass {
    private static violate SingletonClass instance = null;
    public static SingletonClass getInstance() {
        if (instance == null) {
            synchronized(SingletonClass.class) {
                if (instance == null) {
                    instance = new SingletonClass();
                }
            }
        }
        return instance;
    }
}

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

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

相关文章

PostCSS通过px2rem插件和lib-flexible将px单位转换为rem(root em)单位实现大屏适配

目录 文档postcss中使用postcss-plugin-px2rem安装postcss-plugin-px2rem示例默认配置 webpack中使用postcss-plugin-px2rem项目结构安装依赖文件内容 大屏适配参考文章 文档 类似的插件 postcss-plugin-px2rem https://www.npmjs.com/package/postcss-plugin-px2remhttps://g…

【深度学习基础】Pytorch框架CV开发(2)实战篇

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

我的大语言模型微调踩坑经验分享

由于 ChatGPT 和 GPT4 兴起,如何让人人都用上这种大模型,是目前 AI 领域最活跃的事情。当下开源的 LLM(Large language model)非常多,可谓是百模大战。面对诸多开源本地模型,根据自己的需求,选择…

文件夹还在,里面文件没了?问题这样解决

文件夹还在但文件无故消失怎么办?文件的消失对于我们来说可能是个令人沮丧且困惑的问题。有时候,我们可能会发现文件夹依然存在,但其中的文件却消失了。在这篇文章中,我们将探讨为什么电脑文件会无故消失的原因,并提供…

【Kafka】基本概念

文章目录 一、消息队列的流派1.1 有Broker1.1.1 重topic1.1.2 轻topic 1.2 无Broker 二、kafka安装三、kafka基本术语四、发送消息五、消费消息六、单播消息七、多播消息八、查看消费组的详细信息九、主题topic十、分区十一、kafka中消息⽇志⽂件中保存的内容 一、消息队列的流…

微信-Native支付(扫二维码支付)工具类 2023最新保姆教程

0、照着微信开发文档 取到证书、秘钥等 好几个key 1、获取商户号merchantId 账户中心->商户信息->微信支付商户号 3、获取商户证书序列号merchantSerialNumber 账户中心->API安全->API证书管理 5、获取appID 产品中心->AppID账号管理 1、这个链接教你获取各…

1220*2440mm建筑模板木工板:桥梁工程中的覆膜板选择

在桥梁工程中,选择合适的建筑模板木工板至关重要。其中,1220*2440mm规格的建筑模板木工板作为一种常见的选择,特别适用于混凝土工程和桥梁建设。本文将重点介绍这种规格的木工板作为覆膜板在桥梁工程中的应用。 1220*2440mm建筑模板木工板是一…

RISC Zero zkVM架构

1. 引言 RISC Zero zkVM为: 基于 FRI PLONK 构建的采用Von Neumann架构的ZK Machine将RISC-V微控制器 具化为 某基于STARK的证明系统,的微架构和编码机制。 2. Row (Time) Structure 一个cycle对应1个memory transaction,对用户传入的程…

嵌入式Linux HID多指触控/触摸设备报表描述符

这里只做一下简单记录,更为详细的修改流程后续的文章再介绍。 报表描述符 0x05, 0x0D, // Usage Page (Digitizer) 0x09, 0x04, // Usage (Touch Screen) 0xA1, 0x01, // Collection (Application) 0x85, 0x01, // Report ID (1) 0…

jbase实现业务脚本化

经过晚上和早上的努力,终于补上框架最后一块了,业务脚本侦听变化后自动编译jar包和调用,实现维护成本低,开发效率高的框架的基本体系。 实现自动编译jar包的类 package appcode;import org.w3c.dom.Document; import org.w3c.do…

Android 数据恢复的顶级软件分享

人们经常向我们询问有关 Android 数据恢复软件的信息以及它们是否有用。而且,我们给他们讲了两个朋友的故事——凯伦和亚历克斯。他们都丢失了 Android 手机上的一些重要数据。 丢失数据确实是一个令人心碎的时刻,根据丢失的文件,可能会让您…

Linux高级命令(扩展)三

一、date命令 1、date命令的作用 date命令的主要作用:用于获取计算机操作系统的系统时间 2、获取计算机的系统时间 # date 3、定制时间格式 # date "%F %T %Y %m %d %H %M %S" %F : 2020-04-03 %T : 09:45:36 %Y : 年 %m : 月 %d : 日 %H : 小时 %M…

这个超实用的门禁技巧,让办公楼安全更简单高效!

门禁监控是现代社会中不可或缺的一部分,用于确保安全和管理进出某个区域的人员。随着科技的不断发展,门禁监控已经远离了传统的机械锁和钥匙,变得更加智能化和高效。 客户案例 企业办公大楼 无锡某大型企业在其办公大楼内部部署了泛地缘科技…

【机器学习 | PipeLine】机器学习通用管道最佳实践!!(无论什么问题都能套上,确定不来看看?)

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

任正非说:只有“有为”才会“有位”,任何组织只有在流程中创造价值,才可能获得成长的机会。

你好!这是华研荟【任正非说】系列的第28篇文章,让我们聆听任正非先生的真知灼见,学习华为的管理思想和管理理念。 一、所有一切要符合未来的作战需要,组织是为了作战而存在的,而不是作战服从组织的。 来源于任正非先生…

RK-3399pro 萤火虫firefly 官方unbuntu 固件系统安装搜狗中文输入法

RK-3399pro 萤火虫firefly 官方unbuntu 固件系统安装搜狗输入法(适用于所有基于Ubuntu的UI桌面系统) 一、添加中文语言支持输入法平台fcitx 1.安装fcitx sudo apt-get install fcitx 2.然后设置fcitx为开机自启动 sudo cp /usr/share/applications/fc…

Python进阶之推导式与生成器

文章目录 一、推导式1.列表推导式2.字典推导式3.集合推导式4.元组推导式(生成器推导式) 二、生成器1.生成器表达式2.生成器函数3.send函数 结束语 💂 个人主页:风间琉璃🤟 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联…

【数智化人物展】华院计算董事长、创始人宣晓华:通用大模型只是起点,尚需结合专业知识方能解决行业核心问题...

宣晓华 本文由华院计算董事长、创始人宣晓华投递并参与《2023中国企业数智化转型升级先锋人物》榜单/奖项评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 大模型的出现,正在开启着国内新一轮AI热潮。 某种程度上,真正在当下决定企业成败的&#…

22款奔驰S400L升级原厂 360全景影像 高清环绕的视野

您是否经历过这种场面呢? 停车位,狭窄障碍停车困难 避免盲区,倒车盲区危及生命安全 狭窄路段,无法判断是否安全通过 视角盲区,小孩站在视野盲区看不到 360度无缝3D全车可见,解决各个视角盲区&#xff…

开发一款直播弹幕游戏需要多少钱?

开发一款直播弹幕游戏需要多少钱?有好多朋友在咨询过弹幕游戏的开发价格后,都会比较吃惊,一款体量这么小的游戏为什么动辄就要几万块甚至十几万? 我来给你们说分析一下原因,这种游戏如果脱离开直播间,可以…