自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

wpml_java 技术博客

java 源码讲解

  • 博客(26)
  • 资源 (2)
  • 收藏
  • 关注

原创 ConcurrentSkipListMap 源码全解

1、将数据插入数据节点链表,插入过程中如果发现节点被删除将帮助从链表中删除节点,如果发现该 key 已存在,根据 onlyIfAbsent 判断是否更新 value 值2、通过随机数控制是否增加索引节点和索引层级,每次最多增加一层

2023-08-23 13:34:55 151

原创 ConcurrentHashMap 源码全解二

**1、每个节点或者是黑色,或者是红色。** **2、根节点是黑色。** **3、每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]** **4、如果一个节点是红色的,则它的子节点必须是黑色的。** **5、从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点**

2023-08-21 17:21:04 82

原创 ConcurrentHashMap 源码全解一

该篇主要讲解了数据插入操作流程以及数组扩容流程,插入过程通过 synchronized 和 CAS 保证多线程安全

2023-08-19 19:50:40 75

原创 JUC 之队列 SynchronousQueue 详解

基于单链表实现的 FIFO 队列,队列中阻塞的节点要么全是 put 线程,要么全是 take 线程,一个阻塞等待另一个线程过来与之进行匹配,否则将一直阻塞在队列中直到被匹配完成退出或阻塞超时退出或被中断退出。在阻塞等待被匹配的过程中,如果你的前一个节点是头结点将会进行自旋优化,尽量避免进入 OS 阻塞。我们还发现作者为了标识节点已被取消,采用了将 节点的 item 设置为 节点 自身,这样其它线程在与之进行匹配 CAS 操作将会失败。通过将 节点的 next 赋值为节点本身,用来标识节点从队列中移除了。

2023-08-07 16:43:29 116

原创 @RefreshScope 注解引起的kafka无法消费问题排查

通过上述源码我们可以看到 CanalListenerAnnotationBeanPostProcessor 实现了 BeanPostProcessor(简称 BPP) 和 SmartInitializingSingleton 这两个接口,了解 spring 的同学应该知道 spring Bean 在完成实例化后会回调 BeanPostProcessor 接口中的方法(每个对象实例化时都会回调),但是回调也是有条件限制的,后面的 spring 源码中我们会看到;

2023-08-03 14:55:28 244

原创 JUC 之 队列 Exchanger 详解

在一个同步点上,线程可以配对和交换成对中的元素。每个线程在进入exchange方法时携带自身数据,与另一线程进行匹配,配对成功时两个线程相互交换数据并返回对方的数据。交换器可以看作是双向形式的同步队列。

2023-07-27 13:54:39 68

原创 JUC 之队列 LinkedBlockingQueue 详解

take 方法中 为什么使用 while 循环判断 count 是否等于 0?在多线程并发的情况下,当生产者向队列中插入了一条数据,由于 count 使用的是 AtomicInteger 的原子类,而 Condition 的唤醒操作是将等待的线程节点先移动到锁竞争的竞争队列中,然后再去抢锁等待OS唤醒调度执行

2023-07-26 09:41:38 62

原创 JUC 之队列 ArrayBlockingQueue 详解

take 方法中 为什么使用 while 循环判断 count 是否等于 0?在多线程并发的情况下,当生产者向队列中插入了一条数据,由于 count 使用的是 AtomicInteger 的原子类,而 Condition 的唤醒操作是将等待的线程节点先移动到锁竞争的竞争队列中,然后再去抢锁等待OS唤醒调度执行,但是在此唤醒状态过程中如果有其它线程先拿到锁把数据取走了,然后又将 count 值减为了 0,如果使用 if 条件将不会从新检测队列中的值,这时就有问题了。

2023-07-24 17:22:22 73

原创 JUC 之 队列基础篇讲解

Queue 接口继承自 Collection 接口,说明队列也是一个集合容器,用来存储数据的。通常队列的实现方式为FIFO(先进先出)或 LIFO(后进先出),总是从一头插入一头取数据。下面我们来看看 Queue 额外提供了什么功能。

2023-07-24 10:14:14 176

原创 JUC 之 CyclicBarrier 源码分析

通过上述源码可以看到,只有所有线程都到达屏障点后才属于正常情况,这时会调用 nextGeneration 方法唤醒所有等待线程、复位 count、生成新的 generation。而其他线程可能会因为被中断或超时都会造成本轮次操作的失败,即 generation.broken 被设置为了 true,其它线程检测到该值被设置纷纷抛出 BrokenBarrierException 异常而退出等待

2023-07-20 13:52:21 53

原创 JUC 之 ReentrantLock 源码解析

前面我们学习了 AQS 的源码,了解了 AQS 的实现原理,为我们后面即将学习的 ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore 等奠定了扎实的基础。Java 中同步器的实现均离不开 AQS 的支持。那么下面我们就从 ReentrantLock 开始逐一进行讲解。

2023-07-15 19:38:30 42

原创 AQS 之 Condition 源码剖析

前面我们详细讲解了互斥锁与共享锁的源码实现。有一种情况,我们可不可以控制程序在满足某一条件在继续执行呢?答案是 能,怎么做呢?JDK 提供了 Condition 条件接口,我们通过实现该接口就能控制程序的执行,下面我们来看看 AQS 中 ConditionObject 的具体实现。在看它的时候,我们只需要记住一点,针对 ConditionObject 的所有操作都是线程安全的,因为只有在先获取到锁才能去操作 ConditionObject。

2023-07-14 09:51:57 63

原创 AQS 之 共享锁 源码剖析

上一篇我们详细讲解了互斥锁的源码实现,也即同一时刻只有一个线程获得锁,其它参与竞争的线程必须等待。有一种情况是允许多个线程同时获得锁,如读写锁(ReentrantReadWriteLock)允许所有读线程同时获取锁,写线程阻塞,也即读读共享,读写互斥,写写互斥。那么接下来我们就来看看共享锁的源码实现。

2023-07-14 08:49:24 269

原创 AQS 之 互斥锁 源码剖析

AQS 是 AbstractQueuedSynchronizer 类的简称,AQS 是一个用来构建锁和同步器的基础框架,想要了解 Java 的锁实现及其底层原理就必须先了解 AQS 完成了什么,提供了哪些功能。有了AQS的基础支撑我们后面再去学 Java 锁(如ReentrantLock、ReentrantReadWriteLock、Semaphore等)相关类的源码时就会觉得很轻松。那么下面我们就开始进入 AQS 的源码之旅。

2023-07-09 11:23:55 90

原创 springboot2.4 + mybatis-plus3.4 + sharding-jdbc 5.0.0分库分表+读写分离实现案例

记录一下 shardingsphere-jdbc 5.0.0版本 分库分表 + 读写分离 实现本示例采用 Java bean 配置方式代码已上传gitee仓库,感兴趣的自行下载查看,能力有限仅供参考1、创建数据库表,数据库脚本放在sql文件夹下了2、创建springboot项目,本示例版本采用 2.4.23、pom.xml<dependency> <groupId>org.springframework.boot</groupId> <

2022-03-17 17:01:01 1384 2

原创 JUC 之 CountDownLatch 源码分析

以上就是 CountDownLatch 的实现原理。就是利用 AQS 共享锁机制的同步器 Sync 来实现的。 此处读者需要注意的是 CountDownLatch 一旦创建只可使用一次,不能重复使用

2023-07-19 15:46:21 33

原创 JUC 之 Semaphore 信号量

利用 AQS 的共享锁机制,初始设置一个固定 state 值(初始容量),当有线程需要获取访问权时,检测 state 是否有可用资源,state > 0 代表有资源可用,获取到访问凭证后将 state 减 1;只要 state > 0 其他线程就可以获取访问凭证,直到 state = 0。利用该特性就可以完成对接口的限流操作,控制并发请求量。

2023-07-18 16:29:34 60

原创 JUC 之 ReentrantReadWriteLock 读写锁

通过上述源码的学习,我们知道了读写锁的实现流程。AQS 提供 state 单变量和 队列的功能,ReentrantReadWriteLock 通过操作这两个信息完成自己的功能。通过将一个整型变量 state 切割为 高低 16 位,分别用于保存读锁和写锁的信息,高 16 位表示读锁,低 16 位表示写锁。

2023-07-17 11:22:38 102

原创 JUC源码系列之ThreadPoolExecutor

** 通过位组合的方式将线程池的运行状态和工作线程数保存在一个变量 ctl 中,高三位表示运行状态,低 29 位保存工作线程数 */ private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING , 0));/** COUNT_BITS 29位 */ private static final int COUNT_BITS = Integer . SIZE - 3;

2023-03-30 15:26:15 67

原创 JUC源码系列之LinkedBlockingQueue

基于单向链表实现的有界阻塞队列,遵循先进先出(FIFO)原则。可用于实现一个生产者消费者模型,由于内部使用了 takeLock 和 putLock 两把锁,还有notEmpty 和 notFull 两个条件变量,因此它可以做到读与写并行操作。使用 AtomicInteger 记录队列中元素的个数。/** 队列的容量,默认为 int 的最大值 */ private final int capacity;

2023-03-28 15:59:46 60

原创 JUC源码系列之SynchronousQueue

** 表示当前节点是消费者线程 */ static final int REQUEST = 0;/** 表示当前节点是生产者线程 */ static final int DATA = 1;/** 表示当前节点是匹配节点线程 */ static final int FULFILLING = 2;/** 栈的头节点 */ volatile SNode head;SNode节点变量介绍// 指向下一个节点的指针 volatile SNode match;

2023-03-22 17:28:09 119

原创 AQS之ReentrantLock实现原理分析

加入阻塞队列实现:通过以下源码我们发现是尾插法入队,并且优先关连prev指针(新节点的prev优先连上原tail指向的节点)(如下图2),延迟更新 tail 指针和 原tail节点的next指针。公平与非公平唯一的区别在于两者在获取锁的时候是否检查竞争队列是否有正在等待的线程,对于公平锁来说队列中有值时,线程直接进入队列阻塞等待,而非公平锁在获取锁时不会检查队列是否有值,上来先尝试去抢锁,抢不到在进入队列阻塞等待。2、互斥锁又分为公平锁和非公平锁两种实现,那何为公平锁?2、入队成功后释放已获得的锁。

2023-03-09 20:22:31 107

原创 JUC-LongAdder

对于AtomicLong原子类虽然能保证线程操作的原子性,但是在多线程竞争的情况下同时只会有一个线程能获取到锁进行累加操作,其他CPU只能在那自旋空转(浪费CPU资源)。而对于LongAdder来说,当存在多线程并发操作时,会将其累加操作分散到不同的cell中,增加的了线程并行度(最大限度的压榨CPU,减少CPU空转),进而提升了性能。累加操作,核心就是当存在多线程竞争的时候,将CAS操作分散到不同的cell 中,最后获取总值的时候将各个cell中的值与base的值累加返回。1、cells数组没有初始化。

2023-03-09 19:57:09 52

原创 ThreadLocal内存泄漏源码分析

TLM中存放的是一系列的Entry对象,entry中 key 是弱引用的TL,value是我们需要保存的值(强引用),通过上图的是示例代码发现,当TL被回收后发现value的值还存在,此时如果该线程一直处于执行中,那么value的值就属于内存泄漏(该value值永远存在无法被GC)。通过当前TL算出其对应的索引下标 i 的值,从当前下标向后遍历知道数组项为空停止,找到当前项清除即可,调用expungeStaleEntry方法清除其他失效的数组项。每个线程都有独立的TL,线程私有变量,多线程安全。

2023-03-09 19:52:41 131

原创 基于现有项目构建自定义maven archetype

什么是maven archetype?详细定义参考maven官网。下面开始我们自定义archetype实现(基于现有项目构建)1、根据需要构建maven项目本示例根据 springboot + mybatis-plus + shardingsphere + nacos 实现,仅供参考代码上传giteegitee地址:https://gitee.com/wpml/lc-maven-rw-java.git自行搭建自己所需项目,也可以参考本人gitee上的代码,有啥疑问欢迎留言探讨项目结构如下2

2022-03-21 11:04:18 345

原创 sharding-jdbc 5.0.0 读写分离 实现

sharding-jdbc 5.0 使用,基于yml配置方式实现

2022-03-16 13:17:51 1993

commons-codec-1.9.jar

commons-codec-1.9.jar

2015-09-09

jdk环境变量

在系统变量里点击新建,变量名填写JAVA_HOME,变量值填写JDK的安装路径,在这里就填写“C:\Program Files\Java\jdk1.6.0_26”了。 在系统变量里点击新建变量名填写CLASSPATH,变量值填写“.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar”。注意不要忘记前面的点和中间的分号。 在系统变量里找到Path变量,这是系统自带的,不用新建。双击Path,由于原来的变量值已经存在,故应在已有的变量后加上 “;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin”。注意前面的分号。

2015-09-09

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除