Java并发源码分析-ConcurrentHashMap源码分析
参考文献
面试 ConcurrentHashMap ,看这一篇就够了!
ConcurrentHashMap
JDK1.7
在 JDK1.7 中,ConcurrentHashMap 使用了分段锁的机制,将哈希表分为多个 Segment,每个 Segment 上都有一把锁,不同的 Segment 可以被不同的线程同时访问,这样可以提高并发度,减少锁的争用。
每个 Segment 内部使用一个 HashEntry 数组来存储元素,每个 HashEntry 都是一个链表的头节点,通过链表的方式解决哈希冲突。这种数据结构的设计使得并发情况下,只有访问同一个 Segment 上的元素才需要加锁,其他 Segment 上的元素可以并发访问,提高了并发度。
JDK1.8之后
在 JDK1.8 中,ConcurrentHashMap 放弃了 Segment 分段锁的机制,采用了与HashMap相同的Node 数组+链表+红黑树的结构。这样可以减少了锁的竞争,提高了并发度,同时也减少了内存占用。
在 JDK1.8 中,ConcurrentHashMap 使用了CAS +synchroniz ...
Java并发编程-原子操作类概览
参考文献
原子操作类
由于变量类型的关系,在J.U.C中提供了12个原子操作的类.这12个类可以分为四大类:
基本类型:
AtomicBoolean: 原子更新布尔类型
AtomicInteger: 原子更新整型
AtomicLong: 原子更新长整型
数组类型:
AtomicIntegerArray: 原子更新整型数组里的元素
AtomicLongArray: 原子更新长整型数组里的元素
AtomicReferenceArray: 原子更新引用类型数组里的元素
引用类型:
AtomicReference: 原子更新引用类型
AtomicReferenceFieldUpdater: 原子更新引用类型里的字段
AtomicMarkableReference: 原子更新带有标记位的引用类型,可以原子更新一个布尔类型的标记位和引用类型.
字段更新:
AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器
AtomicLongFieldUpdater: 原子更新长整型字段的更新器
AotmicStampedReference: 原子 ...
Java基础-SPI机制
参考文献
Java SPI 机制详解
SPI机制
JDK SPI(Service Provider Interface)机制是一种基于接口的服务发现机制,它允许应用程序在运行时动态地查找和加载实现某个接口的服务提供者.
在每次类加载的时候会先去找到 class 相对目录下的 META-INF 文件夹下的 services 文件夹下的文件,将这个文件夹下面的所有文件先加载到内存中,然后根据这些文件的文件名和里面的文件内容找到相应接口的具体实现类,找到实现类后就可以通过反射去生成对应的对象,保存在一个 list 列表里面,所以可以通过迭代或者遍历的方式拿到对应的实例对象,生成不同的实现.
JDK SPI 机制的基本原理如下:
定义接口: 定义一个接口,其实现类将作为服务提供者.
配置文件: 在 META-INF/services目录下创建一个以接口全限定名命名的文本文件,该文件的内容是实现该接口的服务提供者的全限定名.
文件名一定要是接口的全类名,然后里面的内容一定要是实现类的全类名,实现类可以有多个,直接换行就好了,多个实现类的时候,会一个一个的迭代加载.
服务加 ...
I/O模型
参考文献
6.2 I/O Models
小林coding-什么是零拷贝?
Netty-零拷贝
Netty零拷贝机制
Zero Copy I: User-Mode Perspective
I/O读写的基本原理
为了避免用户进程直接操作内核,保证内核安全,操作系统将内存(虚拟内存)划分为两个部分:
内核空间(Kernel-Space)
用户空间(User-Space)
针对Linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间
I/O 请求可以分为两个阶段,分别为调用阶段和执行阶段.
第一个阶段为I/O 调用阶段,即用户进程向内核发起系统调用.
第二个阶段为I/O 执行阶段.此时,内核等待 I/O 请求处理完成返回.
该阶段分为两个过程:首先等待数据就绪,并写入内核缓冲区;
随后将内核缓冲区数据拷贝至用户态缓冲区.
在Linux系统中,内核模块运行在内核空间,对应的进程处于内核态;用户 ...
生活日常-上海日常信息
参考文献
各种价费标准一目了然!2023年版上海市市民价格信息指南公布→
上海地铁
2023年版上海市市民价格信息指南摘要
上海地铁线路图
注: 图片来源于上海地铁,仅供自己参考,若有侵权,请联系删除.
11号线运行时刻表
注: 图片来源于上海地铁,仅供自己参考,若有侵权,请联系删除.
公交车发车时间表
18路公交发车时间表(数据更新时间20230423)
15路公交发车时间表(数据更新时间20230423)
15路区间公交发车时间表(数据更新时间20230423)
生活日常-骑行
参考文献
https://www.sheldonbrown.com/chinese/tire-sizing.html
限位螺丝
H限位螺丝
H螺丝是调整后拨导轮相对于飞轮最小齿的限位螺丝,通常在螺丝附近会标注“H”的英文字母,代表高速“High”的意思.
逆时针转动螺丝,导轮会越靠近外侧;
顺时针转动螺丝,则导轮会靠近内侧.
导轮的位置调整到与最小齿轮最外侧相互垂直为佳,可防止链条因为变速幅度过大掉入车架与飞轮之间的间隙中.
L限位螺丝
L螺丝是调整后拨导轮相对于飞轮最大齿的限位螺丝,通常在螺丝附近会标注“L”的英文字母,代表低速“LOW”的意思.
逆时针转动螺丝,导轮会越靠近外侧;
顺时针转动螺丝,则导轮会靠近内侧.
导轮的位置调整到与最大齿轮相互垂直为佳,可防止链条因为变速幅度过大掉入辐条与飞轮之间的间隙中.
导轮与飞轮距离螺丝
该螺丝是调整后拨导轮相间于飞轮间距的限位螺丝,通常独立一颗靠近后拨勾,因为变速时后拨张力的大小会影响变速的速度,理论上来说后拨导轮越靠近飞轮是最好的,但是靠得太近导轮与飞轮的变速齿会相互碰撞发出“咔咔”的响声.
调整的间隙是导轮与 ...
Netty-ByteBuf
参考文献
https://netty.io/4.1/api/index.html
ByteBuffer
12345678910+--------------------------------------------------------------------------------+| ByteBuffer |+-------------------+-----------------------------------+-------+----------------+| | 可读区 (readable) | | |+--------+----------+-----------------------------------+-------+-------+--------+| | | [数据, 数据, 数据, 数 ...
Netty(四)-线程模型
参考文献
Scalable IO in Java --Doug Lea
线程模型
基本的线程池化模式可以描述为
从池的空闲线程列表中选择一个Thread,并且指派它去运行一个已提交的任务(一个Runnable的实现);
当任务完成时,将该Thread返回给该列表,使其可被重用。
Reactor线程模式
Reactor线程模式是一种基于事件驱动的编程模式.
它将事件的处理分解为两个基本操作:事件的分发和事件的处理.
Reactor模式通常包括以下角色:
Reactor:Reactor是整个模式的核心,它负责监听和分发事件,将事件分发给相应的处理器进行处理.Reactor通常使用事件循环来轮询事件队列,将事件分发给相应的处理器.
Handler:Handler是事件处理器,负责处理具体的事件.当Reactor将事件分发给Handler时,Handler会执行相应的业务逻辑,并将处理结果返回给Reactor.
Acceptor :Acceptor 是连接处理器,负责处理新的连接请求.当有新的连接请求到来时,Acceptor 会创建一个新的连接,并将其注册 ...
解决方案-ID生成器
参考文献
雪花算法
雪花算法是一种用于生成全局唯一ID的算法,也称为Twitter雪花算法。它能够在分布式系统中生成唯一的ID,而不需要集中式的ID生成器来维护。雪花算法的原理如下:
雪花算法的ID由64位二进制数组成,其中第1位为符号位,始终为0;第2-42位为时间戳,记录当前时间与一个固定的起始时间之间的差值,精确到毫秒级别;第43-52位为机器ID,用于标识不同的机器,最多能够标识1024台机器;第53-64位为序列号,表示同一毫秒内生成的不同ID,最多能够生成4096个ID。
在生成ID之前,需要先初始化一些参数,包括起始时间、机器ID等。起始时间可以设置为某个固定的时间点,机器ID可以通过配置文件或者其他方式来获取。
在生成ID时,雪花算法会先获取当前时间,计算出时间戳,并将时间戳左移22位,使其占据ID的前42位。然后再将机器ID左移12位,占据ID的43-52位。最后,将序列号加1,并将其与机器ID和时间戳拼接起来,即为最终的ID。
如果在同一毫秒内生成的ID超过了4096个,序列号会重新从0开始计数。如果在同一毫秒内生成的ID超过了4096个,并且当前时间已经超过了 ...
分布式事务
参考文献
分布式事务,这一篇就够了
理论
事务
事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态.事务是逻辑上的一组操作,要么都执行,要么都不执行(支持连续SQL的集体成功或集体撤销.);
事务应该具有 4 个属性:原子性、一致性、隔离性、持久性.这四个属性通常称为 ACID 特性.
分布式事务
分布式事务指在分布式系统中,涉及到多个操作的一组事务,这些操作可能分布在不同的计算机上,这些操作必须要保证原子性、一致性、隔离性和持久性,以确保数据的正确性和可靠性.
在分布式系统中,由于存在多个数据节点,因此需要保证数据的一致性.如果在分布式系统中的每个节点都采用独立的事务处理,则可能会导致数据不一致的问题.为了解决这个问题,需要引入分布式事务,以保证多个节点之间的数据操作是一致的.
本质上来说,分布式事务就是为了保证不同数据库的数据一致性.
分布式事务的实现可以采用两种方式:基于两阶段提交协议(2PC)和基于补偿事务的方案.基于2PC的方案是一种经典的实现方式,它通过协调器来实现多个节点之间的事务协调, ...