Java八股文 ---Java并发篇

news2024/12/27 0:04:50

线程安全

线程安全就是多个线程去执行某类,这个类始终能表现出正确的行为,那么这个类就是线程安全的

我们判断是否要处理线程安全问题,就看有没有多个线程同时访问一个共享变量

  • 能不能保证操作的原子性,考虑atomic包下的类够不够我们使用。
  • 能不能保证操作的可见性,考虑volatile关键字够不够我们使用
  • 如果涉及到对线程的控制(比如一次能使用多少个线程,当前线程触发的条件是否依赖其他线程的结果),考虑CountDownLatch/Semaphore等等。
  • 如果是集合,考虑java.util.concurrent包下的集合类。
  • 如果synchronized无法满足,考虑lock包下的类

死锁:当前线程拥有其他线程需要的资源,当前线程等待其他线程已拥有的资源,都不放弃自己拥有的资源

避免的方法:

固定加锁顺序

尽可能缩短加锁范围,等到真正操作共享变量时再加锁

使用可释放的定时锁

CAS

CAS是典型的乐观锁

乐观锁:认为其他线程不会同时修改数据,因此在更新数据时,不会先对数据进行锁定,而是通过版本号等机制判断在此期间是否有人修改了数据。如果别人修改了数据,则放弃操作,否则执行操作。

悲观锁:相反,在操作数据时认为其他线程会同时修改数据,因此直接对数据进行锁定,直到操作完成后才会释放锁。在此期间,其他线程不能修改数据。

CAS的全称为compare and swap,比较并交换,是原子性的操作

CAS 有三个操作数:当前值A、内存值V、要修改的新值B

假设 当前值A 跟 内存值V 相等,那就将 内存值V 改成B

假设 当前值A 跟 内存值V 不相等,要么就重试,要么就放弃更新

将当前值与内存值进行对比,判断是否有被修改过,这就是CAS的核心

为什么要先比较?

如果内存中的值已经被其他线程修改过,那么这个值与预期值不同,CAS操作就会失败,需要重新尝试。因此,通过比较预期值和内存中的值,可以保证数据的一致性和操作的原子性

LongAdder

阿里巴巴开发手册提及到 推荐使用 LongAdder 对象,比 AtomicLong 性能更好(减少乐观锁的重试次数)这是为什么

LongAdder内部维护了一个或多个变量,这些变量被称为"cell"。每个线程都可以独立地访问这些变量进行加法操作,而不会发生竞争。当多个线程同时对同一个变量进行加法操作时,LongAdder会将这些加法操作分摊到不同的"cell"上,从而减少竞争条件的出现。

原理

LongAdder的底层实现原理主要包括两个重要概念:“Cell"和"Base”。

“Cell”(单元)
LongAdder内部维护了一个或多个"cell",每个"cell"都是一个独立的变量,用于存储部分加法操作的结果。在初始化时,默认情况下会创建一个"cell"。

“Base”(基准)
除了"cell",LongAdder还维护了一个名为"base"的变量,用于存储没有被分配到"cell"的加法操作的结果。"base"是一个普通的long类型变量。

当一个线程进行加法操作时,LongAdder会采取以下策略:

如果当前线程是第一个进行加法操作的线程,那么直接将操作的结果累加到"base"上。
如果当前线程不是第一个进行加法操作的线程,那么LongAdder会将操作的结果累加到当前线程所分配的"cell"上。
当多个线程同时进行加法操作时,每个线程都会被分配到一个独立的"cell",从而减少了竞争条件。

当需要获取最终的加法结果时,LongAdder会将"base"和所有"cell"中的值进行求和,得到最终的结果。

需要注意的是,LongAdder在进行求和操作时,并不会阻塞其他线程的加法操作。这样就实现了高并发环境下的高性能加法操作

Synchronized

悲观锁

一种互斥锁,一次只能允许一个线程进入被锁住的代码块

synchronized是Java的一个关键字,它能够将代码块/方法锁起来

如果synchronized修饰的是实例方法,对应的锁则是对象实例

如果synchronized修饰的是静态方法,对应的锁则是当前类的Class实例

如果synchronized修饰的是代码块,对应的锁则是传入synchronized的对象实例

当使用synchronized修饰静态方法时,对应的锁就是当前类的Class实例。这里的"锁"是指用于同步控制的对象,即被上锁的目标。

在Java中,synchronized关键字用于实现同步控制,确保同一时刻只有一个线程可以执行某个方法或代码块。当一个线程进入同步方法或代码块时,它会获取对应的锁,如果其他线程也想要获取这个锁,则会被阻塞,直到第一个线程释放这个锁。

对于静态方法,如果使用synchronized修饰,则该方法属于类级别的方法,而不是实例级别的方法。因此,在执行该方法时,会使用当前类的Class实例作为锁对象。

这样做的好处是,静态方法属于类本身,而不是类的实例,因此使用类实例作为锁可能会导致不同实例之间的竞争。而使用类级别的锁可以确保同一时刻只有一个线程可以执行该类的静态方法

公平锁

公平锁指的就是:在竞争环境下,先到临界区的线程比后到的线程一定更快地获取得到锁

非公平就很好理解了:先到临界区的线程未必比后到的线程更快地获取得到锁

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

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

相关文章

DASCTF X CBCTF 2023

一、justpaint 1.先是压缩包密码爆破,密码为11452,然后开始代码审计,发现是一个线性的神经网络。 源代码如下: import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt from PIL import Ima…

JVM重点

文章目录 0. 运行流程1. 内存区域划分1.1 堆1.2 Java 虚拟机栈1.3 程序计数器1.4 方法区 2. 类加载机制类加载过程2.1 加载2.2 验证2.3 准备2.4 解析2.5 初始化双亲委派模型 3. 垃圾回收机制3.1 垃圾判断算法3.1.1 引用计数算法3.1.2 可达性分析算法 3.2 垃圾回收算法3.2.1 标记…

01 # 手写 new 的原理

new 做了什么? 在构造器内部创建一个新的对象这个对象内部的隐式原型指向该构造函数的显式原型让构造器中的 this 指向这个对象执行构造器中的代码如果构造器中没有返回对象,则返回上面的创建出来的对象 手写 new 的过程 new 是一个运算符,只能通过函…

Redis Cluster高可用集群原理

目录 一、Redis Cluster和哨兵对比二、槽位定位算法三、集群节点间的通信机制四、集群选举原理五、网络抖动六、Redis集群为什么至少需要三个master节点,并且推荐节点数为奇数?七、集群没有过半机制会出现脑裂数据丢失问题八、跳转重定位九、集群对批量操…

封神工具:腾讯云服务器价格计算器,精准报价一键计算!

腾讯云服务器价格计算器可以一键计算出云服务器的精准报价,包括CVM实例规格价格、CPU内存费用、公网带宽收费、存储系统盘和数据盘详细费用,腾讯云百科txybk.com分享腾讯云价格计算器链接入口、使用方法说明: 腾讯云服务器价格计算器 打开腾…

行业追踪,2023-10-25

自动复盘 2023-10-25 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…

[奇奇怪怪符号]输入法手动输入希腊字母

日常写材料总要输入一些奇奇怪怪符号,虽然知道有一张表,可以在上面选,但是在文本编辑器上找到并打开也不是一件容易的事情,(功能多的编辑器就很臃肿,令人眼花缭乱的标签) 很想要简洁的编辑器&a…

文件加密软件(2023十大文件加密软件排行榜)

文件加密软件已成为企业和个人保护文件安全的重要工具。本文将介绍2023年十大文件加密软件的排行榜,以帮助大家了解和选择适合自己的文件加密软件。 本文是根据软件的功能性、安全性、易用性和创新性等多方面指标进行评选,以体现各大文件加密软件的实力和…

C++多态的认识与理解

多态的概念 通俗来说,多态就是多种形态。具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 比方说买高铁票时,如果你是学生的话,买票就有优惠。如果你是军人的话,就可以优先买票。普通人的话&…

聚观早报 |2024年春节连休8天;RTE2023开幕

【聚观365】10月26日消息 2024年春节连休8天 RTE2023开幕 一加12首发“东方屏” 微软公布2024财年第一财季财报 Alphabet Q3业绩好于预期 2024年春节连休8天 国务院办公厅发布关于2024年部分节假日安排的通知。2024年春节,2月10日至17日放假调休,共…

Linux ———— 用户-组

Linux是一个多用户多任务的操作系统。 用户(user): 在Linux系统中,用户是一个拥有独立空间、权限和身份的实体。每个用户都有一个唯一的用户名和用户ID。用户可以登录到系统、读取、写入、执行文件,并按照预设的权限进…

Pytorch使用torch.utils.data.random_split拆分数据集,拆分后的数据集状况

对于这个API,我最开始的预想是从 猫1猫2猫3猫4狗1狗2狗3狗4 中分割出 猫1猫2狗4狗1 和 猫4猫3狗2狗3 ,但是打印结果和我预想的不一样 数据集文件的存放路径如下图 测试代码如下 import torch import torchvisiontransform torchvision.transforms.Compose([torchvision.tran…

算法通关村-黄金挑战K个一组反转

大家好我是苏麟 , 今天带来K个一组反转 , K个一组反转 可以说是链表中最难的一个问题了,每k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后…

索引模型的常见数据结构

索引的出现是为了提高查询效率,三种常见、也比较简单的数据结构 哈希表有序数组搜索树 哈希表 哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的键即 key,就可以找到其对应的值即 Value。哈希的思路很简单…

Python实验项目4 :面对对象程序设计

1:运行下面的程序,回答问题。 (1)说明程序的执行过程; (2)程序运行结果是什么? # (1)说明程序的执行过程; # (2)程序运行…

Python在不同场景下的并发编程方案选择

目录 一、多线程 二、多进程 三、异步IO 四、优缺点分析 五、注意事项 总结 并发编程是软件开发中的重要一环,它允许程序同时处理多个任务,提高程序的运行效率和响应速度。Python作为一种流行的编程语言,提供了多种并发编程方案。 一、…

source insight 使用过程中问题点总结

1. //1 //2 不现实大小的注释。选中Special comment styles即可。

vector详解

迭代器 vector维护的是一个连续线性空间。普通指针可以满足条件作为vector的迭代器。 template <typename T, typename Allocalloc> class vector { public: using value_type T; using iterator value_type*; }; vector::iterator //int* vector::iterator //char* …

HFP协议分析

HFP 全称为Hands-Free Profile&#xff0c;通俗的说就是蓝牙电话协议&#xff0c;可以通过指定好的AT command来控制通话的接听、挂断、拒接等 看协议的一些约定格式 在HFP协议文档里面有一个约定&#xff0c;这里贴出来&#xff0c;每种不同的标识代表不同的意思&#xff0c…

2023年中国高尔夫用品产值、市场规模及细分产品现状分析[图]

高尔夫用品市场是指个人的高尔夫用品&#xff0c;主要包括高尔夫球具、高尔夫球包、高尔夫用球、高尔夫服装、高尔夫鞋、高尔夫帽子、高尔夫手套及相关配件等方面。 随着高尔夫产业的逐步兴起&#xff0c;高尔夫运动受到了越来越多人们的青睐&#xff0c;与此同时&#xff0c;也…