自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

Sumkor的博客

Java and Everything.

  • 博客(22)
  • 收藏
  • 关注

原创 Langchain-Chatchat 部署本地知识库

使用 LangChain-Chatchat,基于在线 LLM 模型(智谱AI API)和离线 Embedding 模型(text2vec-base-chinese 或 bge-base-zh-v1.5)搭建本地知识库。

2024-02-23 16:44:19 1993 1

原创 Lombok 原理与实现

本文主要包含以下内容:Lombok 的实现机制分析。插入式注解处理器的说明及使用。动手实现 lombok 的 @Getter 和 @Setter 注解。配置 IDEA 以调试 Java 编译过程。

2021-12-28 23:50:11 558

原创 阅读 MyBatis 源码:数据库连接池 PooledDataSource

在 MyBatis 中,使用 PooledDataSource 数据源作为连接池对象,在连接池中存储的是 PooledConnection 对象。通过动态代理,实现对原始连接对象的复用,以及多线程间使用数据库连接的隔离。

2021-08-19 16:53:27 639

原创 阅读 MyBatis 源码:插件开发

MyBatis 插件,简单理解为拦截器,它采用动态代理的方式,实现对目标方法的拦截,在前后做一些操作。本文通过分页查询插件的例子,了解 MyBatis 插件的实现原理。

2021-08-18 18:01:42 189

原创 阅读 MyBatis 源码:SQL 执行过程

通过 MyBatis 简单查询的例子,探究 MyBatis 执行 SQL 查询的代码流程,了解源码中 SqlSession、Executor、StatementHandler、ResultSetHandler、MappedStatement 等类的作用。

2021-08-18 17:19:09 194

原创 JDBC 基本流程源码分析

阅读 JDBC 和 MySQL 驱动包的源码,了解在不使用 ORM 框架的情况下 Java 实现 SQL 查询的原理。

2021-08-18 16:47:29 4332

原创 Java 实现数学公式的正则校验和结果计算

Java 实现数学公式字符串的正则校验,并且能够计算出公式的运算结果,支撑多位数、小数点、变量。

2021-07-14 20:39:44 3630 5

原创 阅读 JDK 源码:线程池 ThreadPoolExecutor

上一篇文章介绍了 Thread 类,可知线程随着任务的执行结束而被销毁。但是,由于线程的创建与销毁操作涉及到系统调用,开销较大,因此需要将线程的生命周期与任务进行解耦。使用线程池来管理线程,可以有效地重复利用线程来执行任务。本文将介绍线程池最基础的实现类 ThreadPoolExecutor。本文基于 jdk1.8.0_91文章目录1. 线程池体系2. 构造方法2.1 源码分析2.2 使用说明2.2.1 Core and maximum pool sizes2.2.2 On-demand const

2021-05-16 19:28:26 137

原创 阅读 JDK 源码:线程类 Thread

在 Java 中,使用 Thread 类可以在操作系统层面创建线程,并绑定到对应的 Thread 类实例中。利用线程异步地执行任务,是并发编程的基础。本文通过阅读 Thread 源码,了解线程状态的定义,线程调度的相关方法,以及对线程中断的处理等。本文基于 jdk1.8.0_91

2021-05-13 00:43:59 138

原创 阅读 JDK 源码:异步任务 FutureTask

在 Java 中,Runnable 接口表示一个没有返回结果的任务,而 Callable 接口表示具有返回结果的任务。在并发编程中,异步执行任务,再获取任务结果,可以提高系统的吞吐量。Future 接口应运而生,它表示异步任务的执行结果,并提供了检查任务是否执行完、取消任务、获取任务执行结果等功能。FutureTask 是 Future 接口的基本实现,常与线程池实现类 ThreadPoolExecutor 配合使用。本文基于 jdk1.8.0_91文章目录1. 继承体系2. 属性2.

2021-05-03 15:33:01 116

原创 阅读 JDK 源码:读写锁 ReentrantReadWriteLock

在 JUC 包中,共享锁包括 CountDownLatch、CyclicBarrier、Semaphore 等。ReentrantReadWriteLock 是基于 AQS(AbstractQueuedSynchronizer)框架实现的锁工具,其中定义了两个锁:共享锁 readLock 和独占锁 writeLock。readLock 用于读操作,能同时被多个线程获取;writeLock 用于写入操作,只能被一个线程持有。读锁、写锁均具有公平模式、非公平模式两种获取锁的方式。

2021-05-01 13:31:54 161

原创 阅读 JDK 源码:可重入锁 ReentrantLock

前几篇文章介绍了 AQS(AbstractQueuedSynchronizer)中的独占模式和对 Condition 的实现,这一篇文章来聊聊基于 AQS 框架实现的锁工具:ReentrantLock。ReentrantLock 是一个可重入的互斥锁,也被称为独占锁。具有两种实现:公平锁(fair lock)、非公平锁(non-fair lock)。本文基于 jdk1.8.0_91

2021-04-28 23:50:04 123

原创 阅读 JDK 源码:AQS 对 Condition 的实现

前两篇文章分别介绍了 AQS 框架中的独占模式和共享模式,本篇将介绍 AQS 对 Condition 接口的实现。在阅读本篇之前,建议先了解 AQS 中的数据结构和独占模式的实现原理。JUC 通过 Lock 和 Condition 两个接口实现管程(Monitor),其中 Lock 用于解决互斥问题,而 Condition 用于解决同步问题,而 AQS 对 Lock 和 Condition 接口的实现提供了一个基础的框架。文章目录1. Condition 接口2. Condition 使用3. Con

2021-04-25 20:55:02 110

原创 阅读 JDK 源码:AQS 中的共享模式

AbstractQueuedSynchronizer,简称 AQS,是一个用于构建锁和同步器的框架。上一篇文章介绍了 AQS 的数据结构和独占模式的实现原理,本篇介绍 AQS 共享模式的源码实现。文章目录1. 共享模式1.1 获取锁-acquireShared1.1.1 tryAcquireShared1.1.2 doAcquireSharedsetHeadAndPropagatedoReleaseShared1.2 释放锁-releaseShared

2021-04-25 17:11:36 104

原创 阅读 JDK 源码:AQS 中的独占模式

AbstractQueuedSynchronizer,简称 AQS,是一个用于构建锁和同步器的框架。JUC 包下常见的锁工具如 ReentrantLock、ReentrantReadWriteLock、Semaphore、CountDownLatch 都是基于 AQS 实现的。文章目录1. AQS 框架1.1 继承体系1.2 模板方法2. 数据结构2.1 资源定义2.2 节点定义2.3 同步队列2.4 条件队列3. 独占模式3.1 获取锁-acquire3.1.1 tryAcquire3.1.2 add

2021-04-25 17:03:31 93

原创 阅读 JDK 源码:传递队列 LinkedTransferQueue

LinkedTransferQueue 是一个由链表结构组成的无界阻塞 TransferQueue 队列。接口 TransferQueue 和实现类 LinkedTransferQueue 从 Java 7 开始加入 J.U.C 之中。文章目录1. 继承体系2. 数据结构2.1 节点定义2.2 head 和 tail 节点3. 构造函数4. 数据存取及传递4.1 xfer4.2 匹配过程图示4.3 tryAppend4.4 awaitMatch4.5 自旋次数4.6 unsplice5. 容量6. 总结

2021-04-19 21:38:40 91

原创 阅读 JDK 源码:松弛队列 ConcurrentLinkedQueue

ConcurrentLinkedQueue 是一个由链表结构组成的无界非阻塞队列,是 JDK 中唯一一个并发安全的非阻塞队列。使用无锁算法来保证线程安全,为了减少 CAS 操作造成的资源争夺损耗,其链表结构被设计为“松弛”的,本文对 ConcurrentLinkedQueue 的入队和出队过程进行图解,直观展示其内部结构。文章目录1. 继承体系2. 数据结构2.1 链表节点2.2 head 和 tail 节点基本不变式head 的不变式和可变式tail 的不变式和可变式3. 构造函数4. 入队4.1 源码

2021-03-29 23:20:03 151

原创 阅读 JDK 源码:传递队列 SynchronousQueue

SynchronousQueue 是一个由链表或栈结构组成的阻塞队列,适用于传递性场景,即生产者线程处理的数据直接传递给消费者线程。队列中不直接存储数据元素(队列容量固定为 0)。采用无锁算法,每个线程的存入或取出操作没有被匹配时,将会阻塞在队列中等待匹配,内部的链表或栈结构用于暂存阻塞的线程。当消费者消费速度赶不上生产速度,队列会阻塞严重。文章目录1. 继承体系2. 数据结构3. 构造函数4. 属性5. 容量6. 存入取出操作7. 栈实现栈定义节点定义transferawaitFulfill8. 队列

2021-03-29 22:35:02 95

原创 阅读 JDK 源码:WeakHashMap 和 Reference、ReferenceQueue

WeakHashMap 是一种特殊的 HashMap,它的 key 为 WeakReference 弱引用,并且内置了一个 ReferenceQueue 用于存储被回收的弱引用。阅读 WeakHashMap 源码之前,需要先理解 Reference 和 ReferenceQueue 的机制。理解其基本原理之后,可以使用 HashMap 达到跟 WeakHashMap 一样的效果,文末提供了示例。1. Referencepublic abstract class Reference<T>ex

2021-03-19 09:31:32 227

原创 阅读 JDK 源码:ConcurrentHashMap 扩容总结 (发现源码的BUG!)

这段时间阅读了 JDK 8 的 ConcurrentHashMap 源码,其中扩容的过程涉及技术点繁多,很有必要自己动手对扩容原理进行梳理总结。本文中,我对关键代码编写了单元测试,并且找来了图例,方便理解。编写文章过程,我竟然发现了 JDK 8 版本扩容时对 sizeCtl 的判断有 BUG,具体在第 3.4 节中说明。1. 数据结构使用数组+链表+红黑树来实现,利用 CAS + synchronized 来保证并发更新的安全。1.1 对比 Java7与 Java7 相比,Java8 中的 Co

2021-03-03 00:32:38 353 2

原创 阅读 JDK 源码:HashMap 扩容总结及图解

本文基于 Java8,通过阅读 HashMap 的 resize 方法了解其扩容原理,并对桶上链表的迁移过程进行调试,画图以加深理解。文章目录1. 扩容的时机2. 扩容的源码如果是链结构如果是树结构3. 链表迁移算法执行结果执行过程图示4. 总结1. 扩容的时机HashMap 中 put 入第一个元素,初始化数组 table。HashMap 中的元素数量大于阈值 threshold。threshold = capacity * load factor。当 size > thresho

2021-03-01 09:36:00 7809

原创 HashMap 中的取模和扩容公式推导

为什么 HashMap 容量 capacity 大小是 2 的 n 次幂?为什么使用 e.hash & (capacity - 1) 位运算作取模公式?为什么扩容时使用 e.hash & oldCap 来计算扩容后的数组索引?本文通过推导 HashMap 中的取模和扩容算法以回答上述问题。文章目录1. 按位与(&)运算的理解2. 取模运算2.1 当 e.hash 为正数2.2 当 e.hash 为负数负数取模怎么算整数除法取整取模怎么算3. 扩容运算3.1 推导 e.ha.

2021-02-27 09:55:42 1532 3

空空如也

空空如也

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

TA关注的人

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