JavaEE之多线程进阶-面试问题
一.常见的锁策略
锁策略不是指某一个具体的锁,所有的锁都可以往这些锁策略中套
1.悲观锁与乐观锁
预测所冲突的概率是否高,悲观锁为预测锁冲突的概率较高,乐观锁为预测锁冲突的概率更低。
2.重量级锁和轻量级锁
从加锁的开销角度判断,重量级锁与悲观锁相对应,轻量级锁与乐观锁相对应。(并不是一定的,大多数情况是这样的)
3.挂起等待锁和自旋锁
挂起等待锁,就是悲观锁/重量级锁的一种典型实现。
自旋锁,则是乐观锁/轻量级锁的一种典型实现。
自旋锁,会在不释放cpu资源的情况下一直检测目标锁是否被释放,一旦锁被释放,就立即有机会获得锁(需要消耗更多cpu资源,且要在所冲突不高的时候)
挂起等待锁,就是让出cpu资源,让cpu去做别的事情,等待通知后才会获得锁资源。(时效性低,需消耗更多时间)
4.公平锁和非公平锁
公平锁:先到先得,先阻塞等待的先得到锁,后来后得。
非公平锁:不按照先来后到的顺序,谁争抢到锁归谁(大部分情况下都是使用非公平锁,效率高)
5.可重入锁和不可重入锁
如果对一个线程,针对一把锁重复加锁两次,就有可能出现死锁。
如果把锁设定成“可重入”就可以避免死锁了
可重入锁:对同一个锁资源可以加多次锁
不可重入锁:不可以对同一个锁资源加多次锁
6.读写锁
注:synchronized并非是读写锁
所谓读写锁,就是把“加锁操作”分成两种情况:加读锁,加写锁
读锁:共享锁,读与读操作都能同时拿到锁资源
写锁:排它锁,读写,写读,写写不能同时拿到锁资源
二.synchronized原理
1.特征
1)既是乐观锁,又是悲观锁(自适应)
2)是轻量级锁,也是重量级锁(自适应)
3)不是读写锁
4)挂起等待锁和自旋锁(自适应)
5)是可重入锁
6)非公平锁(锁竞争)
2.锁升级
1)刚开始使用synchronized加锁,首先锁会处于“偏向锁”状态。
偏向锁:相当于一种标记,不是真正加锁(更为轻量高效)
2)遇到线程之间的锁竞争时,会升级到“轻量级锁”。
3)进一步统计锁竞争出现的频次,达到一定程度后,升级到“重量级锁”
无锁=》偏向锁=》轻量级锁=》重量级锁
上述锁升级的过程,主要是为了能够让synchronized这个锁更好的适应不同的场景,降低程序员负担。
注:上诉锁升级的过程是不可逆的
3.锁消除与锁粗化
1)锁消除
编译器会对所写的synchronized代码做出判定,判断这个地方是否确实需要加锁。
如果这个加锁是没有必要的,能够自动把synchronized给干掉。
2)锁粗化
也是一种编译器的优化策略
锁的粗细,是根据锁的粒度来判断的。

代码越多,则粒度越粗,
代码越少,则粒度越细。
锁粗化,就是把多个“细粒度”的锁合并为“粗粒度”的锁

三.CAS
1.概念
CAS全称“compare and swap”,用于比较内存与cpu寄存器种的内容。如果发现相同,就进行交换(交换的是内存和另一个寄存器的值)
如有一个内存中的数据和寄存器1,寄存器2.
比较内存中的数据与寄存器1中的数据是否相等,如果相等,将内存和寄存器2的数据进行交换。
CAS的关键是通过一个cpu指令(原子的)完成了一系列操作,可为编写多线程代码带来新的思路
称为“无锁化编程”
2.使用场景
基于CAS实现“原子类”。
public class Dem1 {private static AtomicInteger count = new AtomicInteger();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int i = 0; i <50000; i++) {count.getAndIncrement();}});Thread t2=new Thread(()->{for (int i = 0; i < 50000; i++) {count.getAndIncrement();}});t1.start();t2.start();t1.join();t2.join();System.out.println("count="+count.get());}
}
3.CAS工作原理
假如有两个线程t1,t2进行自增操作
线程t1先读取到数据,t2后读取到,但t2优先进行cas操作,value+1.
此时调度回t1进行cas操作,能够发现数据发生了变化(value!=oldvalue)。
因此,就能判断出其它线程趁着t1load时修改了value的值,此时便不会进行cas操作,而是再来一次load,确保寄存器中的值是正确的值,然后进行cas。
3.ABA问题
CAS之所以能保证线程安全,重要的一点在于通过CAS比较的过程中,来确认是否有其它线程插入进来执行(通过比较value和oldvalue)
此处是通过判定值是否相同,来判断是否有其它线程修改过。
但是值相同!=没有修改可能。
有可能存在另一个线程修改了值,又修改回去了。这就是ABA问题。
ABA问题产生的原因是因为value可增可减
引入“版本号”,设置版本号只能增加,可以解决ABA问题
相关文章:
JavaEE之多线程进阶-面试问题
一.常见的锁策略 锁策略不是指某一个具体的锁,所有的锁都可以往这些锁策略中套 1.悲观锁与乐观锁 预测所冲突的概率是否高,悲观锁为预测锁冲突的概率较高,乐观锁为预测锁冲突的概率更低。 2.重量级锁和轻量级锁 从加锁的开销角度判断&am…...
费曼学习法没有输出对象怎么办?
费曼学习法并不需要输出对象。费曼学习法的核心在于通过将所学知识以简明易懂的方式解释给自己听,从而加深对知识的理解和记忆。这种方法强调的是理解和反思的过程,而不是简单地通过输出(如向他人解释)来检验学习效果。费曼学…...
Hive优化操作(二)
Hive 数据倾斜优化 在使用 Hive 进行大数据处理时,数据倾斜是一个常见的问题。本文将详细介绍数据倾斜的概念、表现、常见场景及其解决方案。 1. 什么是数据倾斜? 数据倾斜是指由于数据分布不均匀,导致大量数据集中到某个节点或任务中&…...
销冠的至高艺术:让自己不像销售
若想在销售领域脱颖而出,首先是让自己超越传统销售的框架,成为客户心中不可多得的行业顾问与信赖源泉。这不仅是身份的蜕变,更是影响力与信任度质的飞跃。 销冠对客户只吸引不骚扰,不讲自己卖什么,只讲自己能解决什么…...
Hive数仓操作(十一)
一、Hive 日期函数 在日常的数据处理工作中,日期和时间的处理是非常常见的操作。Hive 提供了丰富的日期函数,能够帮助我们方便地进行日期和时间的计算。本文将详细介绍 Hive 中常用的日期函数,并通过具体的示例展示其用法和结果。 1. 获取当…...
C语言初步介绍(初学者,大学生)【上】
1.C语⾔是什么? ⼈和⼈交流使⽤的是⾃然语⾔,如:汉语、英语、⽇语 那⼈和计算机是怎么交流的呢?使⽤ 计算机语⾔ 。 ⽬前已知已经有上千种计算机语⾔,⼈们是通过计算机语⾔写的程序,给计算机下达指令&am…...
陈文自媒体:现在的房价,已经跌到7年前!
今年的国庆北上广深都放开了政策,很多人都放弃旅游去看房了,现在的全民都有一个基本意识,现在的房子已经到了谷底,从各大政策就可以看出来,稍微有点钱的可以出手买房了。 昨天我哥跟我说,现在xx地方的房子…...
基于STM32的智能水族箱控制系统设计
引言 本项目基于STM32微控制器设计一个智能水族箱控制系统。该系统能够通过传感器监测水温、照明和水位,并自动控制加热器、LED灯和水泵,确保水族箱内的环境适宜鱼类生长。该项目展示了STM32在环境监测、设备控制和智能反馈系统中的应用。 环境准备 1…...
java语言基础案例-cnblog
java语言基础案例 象棋口诀 输出 package nb;public class XiangQi {public static void main(String[] args) {char a 马;char b 象;char c 卒;System.out.println(a"走日"b"走田""小"c"一去不复还");} }输出汇款单 package nb…...
MyBatis-Plus 之 typeHandler 的使用
一、typeHandler 的使用 1、存储json格式字段 如果字段需要存储为json格式,可以使用JacksonTypeHandler处理器。使用方式非常简单,如下所示: 在domain实体类里面要加上,两个注解 TableName(autoResultMap true) 表示自动…...
HDLBits中文版,标准参考答案 |2.5 More Verilog Features | 更多Verilog 要点
关注 望森FPGA 查看更多FPGA资讯 这是望森的第 7 期分享 作者 | 望森 来源 | 望森FPGA 目录 1 Conditional ternary operator | 条件三目运算符 2 Reduction operators | 归约运算器 3 Reduction: Even wider gates | 归约:更宽的门电路 4 Combinational fo…...
提升开机速度:有效管理Windows电脑自启动项,打开、关闭自启动项教程分享
日常使用Windows电脑时,总会需要下载各种各样的办公软件。部分软件会默认开机自启功能,开机启动项是指那些在电脑启动时自动运行的程序和服务。电脑开机自启太多的情况下会导致电脑卡顿,开机慢,运行不流畅的情况出现,而…...
数据库简单介绍
数据库是现代信息技术中用于存储、管理和检索数据的重要工具。数据库技术的发展经历了多个阶段,从早期的层次模型和网状模型,到关系型数据库的兴起,再到NoSQL和NewSQL的多样化发展。数据库系统已经成为现代信息系统的核心和基础设施。 数据库…...
运用MinIO技术服务器实现文件上传——利用程序上传图片(二 )
在上一篇文章中,我们已经在云服务器中安装并开启了minio服务,本章我们将为大家讲解如何利用程序将文件上传到minio桶中 下面介绍MinIO中的几个核心概念,这些概念在所有的对象存储服务中也都是通用的。 - **对象(Object࿰…...
C语言 | Leetcode C语言题解之第461题汉明距离
题目: 题解: int hammingDistance(int x, int y) {int s x ^ y, ret 0;while (s) {s & s - 1;ret;}return ret; }...
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
理清 Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系 在开发图形界面应用时,特别是在使用 Qt 框架时,开发者可能会接触到多个概念,如 Qt 3D、QtQuick、QtQuick 3D 和 QML。这些术语分别代表了 Qt 中不同的模块或技术,但由于它们的功能…...
软件设计师(软考学习)
数据库技术 数据库基础知识 1. 数据库中的简单属性、多值属性、复合属性、派生属性简单属性:指不能够再分解成更小部分的属性,通常是数据表中的一个列。例如学生表中的“学号”、“姓名”等均为简单属性。 多值属性:指一个属性可以有多个值…...
第一讲:Go语言开发入门:环境搭建与基础语法
文章目录 环境搭建windows环境搭建Mac环境搭建安装GO使用 Homebrew 安装 Go手动下载安装 Go 配置环境变量配置环境变量检查 Go 是否正确安装 验证安装:编写第一个 Go 程序创建 Go 工作区编写 Hello World 程序运行程序编译程序 常用的 Go 命令 Go语言基础语法1. 变量…...
Linux CentOS stream9配置本地yum源
在Linux系统中,yum源配置是一个重要的环节。把系统安装时配置的国外yum源转换为国内yum源,能够帮助系统快速安装软件包。对于网络环境不稳定或无法联网的系统,配置本地yum源,可以让用户在离线状态下也能进行软件包的安装,十分重要。 一、国内源 在使用Linux的日常工作中…...
std::string
std::string是C标准库中的一个基本类模板,专门用于处理字符串。它提供了一个可变长度的字符序列,以及一系列用于字符串操作的方法。std::string是值类型,这意味着当它作为函数参数传递或赋值时,整个字符串数据会被复制。 std::st…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
