Java面试-线程安全篇

一、synchronized关键字:

  • 基本使用与作用:通过抢票代码示例,展示了synchronized作为对象锁,可避免多线程超卖或抢到同一张票问题,保证代码原子性,同一时刻只有一个线程获得锁,其他线程阻塞。
  • 底层原理:底层是monitor,通过分析字节码信息,可看到monitor entermonitor exit,分别对应上锁和解锁,且有两个monitor exit以防异常导致锁未释放。
  • monitor工作机制monitorwait setentry listowner三个属性。线程尝试获取锁时,若ownernone,则拥有锁;否则进入entry list等待,释放锁后唤醒entry list中线程争抢。调用wait方法的线程进入wait set
  • 锁升级monitor是重量级锁,因涉及用户态和内核态切换,性能低。JDK1.6后引入偏向锁和轻量级锁。一个线程重复获取锁时用偏向锁;两个线程交替获取锁用轻量级锁;多线程竞争时用重量级锁。
  • 三种锁对比:偏向锁性能最好,首次加锁记录线程ID并改标志,后续重入只需判断;轻量级锁每次加锁记录都需CAS操作;重量级锁涉及用户态和内核态切换,性能最低。

二、Java内存模型(JMM)面试题:

  • 概念:定义了共享变量在多线程读写操作的行为规范,保证内存读写指令正确性。
  • 内存划分:分为工作内存和主内存。工作内存是线程私有,存储线程内私有数据,线程间无法互相访问;主内存是共享区域,存储共享变量,多线程同步数据需通过主内存。
  • CAS操作面试题
    • 概念与原理:全称compare and swap,体现乐观锁思想,在无锁情况下保证线程操作共享数据的原子性。线程操作共享数据时,先读取主内存数据到工作内存,修改后与主内存数据比对,相同则更新,不同则自旋重试。
    • 底层实现:依赖unsafe类调用操作系统底层CAS指令,unsafe类提供compare and swap objectintlong三个本地方法。
    • 与锁的对比:CAS是乐观锁,不怕其他线程修改共享变量,通过自旋重试;synchronized是悲观锁,上锁后防止其他线程修改。

三、volatile`关键字:

  • 含义:可修饰共享变量,保证线程间可见性和禁止指令重排序。

  • 线程间可见性:通过代码示例,展示了未加volatile时,线程修改共享变量,其他线程不可见,原因是JIT编译器优化。可通过加VM参数禁用JIT或加volatile关键字解决,项目开发中推荐使用volatile关键字。

  • 指令重排序与volatile关键字

    • 指令重排序概念:代码执行顺序可能与编写顺序不一致,通过测试代码可能出现结果为10的情况判断是否发生重排序,需使用高并发多线程测试工具。
    • volatile解决重排序:在共享变量读写时加入不同屏障,阻止其他读写操作越过屏障。如加在y上能解决问题,加在x上不行。
    • volatile使用技巧:写变量时让volatile修饰的变量在代码最后位置,读变量时让其在代码最上面。
    • volatile特性总结:保证线程间可见性,禁止指令重排序。

四、AQS(抽象队列同步器):

  • AQS定义与对比:是JUC中提供的锁机制,与synchronized对比,它是Java API,需手动开关锁,在锁竞争激烈时性能更好。
  • 基本工作机制:内部有volatile修饰的state,0表示无锁,1表示有锁。线程请求锁需修改state,失败则进入队列等待,队列为先进先出的双向队列。
  • 保证原子性:多个线程抢资源时用CAS设置保证原子性。
  • 公平锁与非公平锁:非公平锁是新线程与队列中线程共同抢资源;公平锁是新线程到队列尾部等待,按队列顺序获得锁。
  • AQS总结:是队列同步器,维护双向队列,用state控制锁,使用CAS保证原子性。

五、ReentrantLock(可重入锁):

  • 特点:可中断、可设置超时时间、可设置公平锁、支持多个条件变量,与synchronized一样支持重入。
  • 实现原理:底层使用CAS和AQS,构造函数可创建公平锁或非公平锁。
  • 工作方式:与AQS类似,用CAS修改状态抢锁,抢到锁将线程挂到属性中,释放锁唤醒队列中线程。
  • 总结:是可重入锁,底层用CAS和AQS,支持公平和非公平锁。

六、synchronized与Lock对比:

  • 语法层面:synchronized是关键字,由JVM提供,C++实现,退出同步块自动释放锁;Lock由JDK提供,Java实现,需调用unlock释放锁。
  • 功能层面:都属悲观锁,有互斥同步和锁重入功能,但Lock有公平锁、可打断、可超时、多条件变量等功能,通过代码演示验证。
  • 性能层面:无竞争时synchronized有优化,性能还行;竞争激烈时Lock性能更好。

七、死锁问题:

  • 死锁产生条件:一个线程同时获取多把锁易发生死锁,如线程T1持有a锁等b锁,线程T2持有b锁等a锁。
  • 死锁诊断工具:使用jps输出JVM中运行的所有进程状态信息,使用jstack查看Java进程内的线程堆栈信息;还可使用jconsole和VisualVM等可视化工具。

八、ConcurrentHashMap:

  • JDK1.7结构:采用分段的数组加列表实现,数组不可扩容,添加数据时用ReentrantLock加锁,性能较低。
  • JDK1.8结构:采用数组加链表加红黑树结构,添加新节点用CAS自旋锁,有链表或红黑树时用synchronized锁首节点,性能更好。
  • 总结:不同版本底层数据结构和加锁方式不同,1.8加锁力度更细。

九、并发程序问题根源:

  • 原子性:一个线程在CPU中的操作不可暂停或中断,如抢票代码可能出现超卖,可通过synchronized或Lock锁保证。
  • 可见性:一个线程对共享变量修改后让另一个线程可见,可加volatile关键字解决,加锁也可但性能不高。
  • 有序性:处理器可能对代码进行指令重排,加volatile关键字可禁止指令重排序。

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

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

相关文章

R 语言科研绘图 --- 其他绘图-汇总2

在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…

【数学建模学习笔记】启发式算法:粒子群算法

零基础小白看懂粒子群优化算法(PSO)一、什么是粒子群优化算法?简单说,粒子群优化算法(PSO)是一种模拟鸟群 / 鱼群觅食的智能算法。想象一群鸟在找食物:每只鸟(叫 “粒子”&#xff0…

【Gitlab】Ubuntu 20.04服务器部署Gitlab

写一个 适用于 Ubuntu 20.04/22.04 的 GitLab 一键部署脚本,包括:安装依赖安装 GitLab CE配置公网 IP 或域名自动开启 HTTPS(Let’s Encrypt)配置防火墙下面是完整脚本:#!/bin/bash# # GitLab 一键安装脚本 # # 1. 检…

Android 15重磅升级:16KB内存页机制详解与适配指南

一、背景随着Android硬件架构的持续演进,新一代设备开始采用16KB内存页(Page Size)机制,逐步替代传统的4KB内存页设计。此项底层变更对应用兼容性产生直接影响,特别是对依赖Native层库、JNI接口或自定义内存管理模块的…

Mybatis-8 动态SQL

动态SQL-官方文档 文档地址 动态 SQL_MyBatis中文网 为什么需要动态SQL 1、动态SQL是MyBatis的强大特性之一 2、使用JDBC或其它类似的框架,根据不同条件拼接SQL语句非常麻烦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一…

PySpark数据输入

PySpark数据输入 1.理解RDD对象 2.掌握PySpark数据输入的2种方法 RDD对象 PySpark支持多种数据的输入,在输入完成后,都会得到一个:RDD类的对象 RDD全称为:弹性分布式数据集(Resilient Distributed Datasets&#xff09…

【系统架构设计(16)】软件架构设计二:软件架构风格:构建系统的设计模式与选择指南

文章目录一、核心思想二、数据流风格:以数据流动为核心的处理模式三、调用返回风格:基于程序调用的层次化组织四、独立构件风格:基于事件驱动的松耦合架构五、虚拟机风格:提供抽象执行环境的架构模式六、仓库风格:以数…

MySQL速记小册(1)

1【Q】:Mysql中的数据排序是怎么实现的?【A】:排序过程中如果字段有索引,则利用索引排序。反之使用文件排序。在文件排序中,如果数据量少则在内存中排序,使用单路排序或双路排序。如果数据量大则利于磁盘文…

20250904 10:45_排查10.1.3.35新QMS系统RMAN备份失败问题(优化脚本里的环境配置,增加了check_oracle_env 函数)

一、RMAN备份失败日志如下 [2025-09-04 04:00:01] 备份脚本启动 [2025-09-04 04:00:01] 开始 RMAN 备份 CDB: ORCLCDB Message file RMAN<lang>.msb not found Verify that ORACLE_HOME is set properly [2025-09-04 04:00:01] RMAN 备份失败! 二、原备份脚本存档…

Vue3源码reactivity响应式篇之EffectScope

概述 EffectScope是Vue3中一个响应式系统的辅助类&#xff0c;用于管理副作用&#xff08;effect&#xff09;的作用域。它可以帮助我们更好地组织和管理多个effect&#xff0c;便于一起停止或暂停以及恢复&#xff0c;避免了全局状态的污染和管理的复杂性。 每一个vue组件的实…

MySQL 日志全解析:Binlog/Redo/Undo 等 5 类关键日志的配置、作用与最佳实践

1 二进制日志&#xff08;Binlog&#xff09;&#xff1a;配置与核心作用 Binlog 是 MySQL 中跨存储引擎的核心日志&#xff0c;记录所有数据修改操作&#xff0c;主要用于主从复制、数据备份恢复与跨库迁移。 1.1 Binlog 核心操作 开启 Binlog 若需开启 Binlog&#xff0c;需在…

springboot 之 HTML与图片生成 (2)

前言 之前写了一篇html转图片的 文章&#xff0c;使用中文时会出现乱码情况&#xff0c;后来又从网上找了下信息&#xff0c;这篇主要介绍下另一个转换库。 依赖 <!-- 用于将html转图片--><dependency><groupId>gui.ava</groupId><artifactId>…

计算机组成原理:计算机的分类

&#x1f4cc;目录&#x1f5a5;️ 计算机组成原理&#xff1a;计算机的分类——从架构到应用的全景梳理一、按处理数据类型分类&#xff1a;从“数字”到“混合”的演进&#xff08;一&#xff09;数字计算机&#xff1a;离散数据的“精准管家”1. 核心原理2. 关键优势3. 典型…

数据结构——单向循环链表代码(补充)

在此前的文章中&#xff08;链接如下&#xff09;&#xff0c;只有单向链表的代码&#xff0c;接下来我们来写单向循环链表&#xff0c;并用其实现一个简单的学生信息链表https://blog.csdn.net/2301_80406299/article/details/151157051?spm1011.2415.3001.10575&sharefr…

【Python自动化】 21.2 Pandas 读取 Excel 时的 dtype 参数完全指南

一、dtype 参数概述 dtype 参数用于指定列的数据类型&#xff0c;在读取 Excel 时非常重要&#xff0c;可以&#xff1a; 提高内存效率避免自动类型推断错误确保数据一致性提升读取性能 二、基本用法 1. 基础语法 import pandas as pd# 指定列数据类型 df pd.read_excel(data.…

gtest全局套件的测试使用

gtest全局套件的测试使用 #include <iostream> #include "gtest/gtest.h" #include <unordered_map>class MyEnvironment: public testing::Environment {public:virtual void SetUp() override{std::cout<<"单元测试前的环境初始化&#xff…

【系统分析师】第7章-基础知识:软件工程(核心总结)

更多内容请见: 备考系统分析师-专栏介绍和目录 文章目录 一、软件工程的基本概念 1.1 定义与意义 1.2 软件工程的基本原则 1.3 核心定义与边界 1.4 四大核心原则 1.5 三大核心目标 二、软件生命周期 2.1 定义与阶段划分 2.2 软件生命周期模型 三、软件开发方法 3.1 结构化方法…

量化基金从小白到大师 - 金融数据获取大全:从免费API到Tick级数据实战指南

量化基金从小白到大师 - 金融数据获取大全&#xff1a;从免费API到Tick级数据实战指南 各位&#xff0c;今天咱们要啃一块硬骨头——金融数据获取。别看这话题基础&#xff0c;它可是整个量化大厦的地基&#xff0c;地基不稳&#xff0c;再牛的策略都得塌房。我见过太多人&…

构建一个“会思考”的房地产数据获取脚本

—— 跨界思维&#xff1a;从认知自适应到房源信息监测 一、认知科学视角&#xff1a;什么是“会思考” 在心理学与认知科学中&#xff0c;所谓“会思考”&#xff0c;并不是指抽象的哲学推理&#xff0c;而是指个体能在复杂环境中不断调整行动策略。 比如&#xff0c;出行时如…

JavaScript的库简介

JavaScript拥有丰富的库生态系统,类似于Python的requests、numpy或C++的Boost。这些库分为两大类:前端库(如React、Vue)和后端/工具库(如Lodash、Axios)。以下是几个核心库的介绍与用法示例。 常用JavaScript库分类 前端UI库 React:Facebook开发的组件化库,用于构建用…