- 博客(112)
- 资源 (2)
- 收藏
- 关注

原创 Java并发编程(十九):ScheduledThreadPoolExecutor总结与源码分析
目录前言使用源码分析前言 ScheduledThreadPoolExecutor主要用于处理延时任务或者定时任务,在平时的工作场景中也有被广泛应用,而我们有了前文关于ThreadPoolExecutor源码的深入理解,这里理解ScheduledThreadPoolExecutor便会顺畅不少。使用ScheduledThreadPoolExecutor的使用还是比较简单,总体来说主要有三种方式提交任务:schedule:scheduleAtFixedRate:scheduleWithFixe
2021-05-09 00:56:59
8486
12

原创 Java并发编程(十八):ThreadPoolExecutor总结与源码深度分析
前言JUC中包含了很多的工具类,不论是第三方工具包,还是自己开发的业务系统,使用最多的还是是线程池,比如普通的线程池ThreadPoolExecutor、带调度的线程池ScheduledThreadPoolExecutor等,本文就从源码层面探究一下ThreadPoolExecutor的实现原理~注:研究线程池源码的目的是为了让自己能够对其有个清晰的认识,理解各个参数设置的含义,以帮助我们正确合理的使用线程池,除非时间非常充足,否则不建议去逐行研究其中的源码,本文也只是分析其核心逻辑的源码~总览
2021-04-28 23:01:19
3890
9

原创 Java并发编程(十六):CyclicBarrier源码分析
CyclicBarrier可以建立一个屏障,这个屏障可以阻塞一个线程直到指定的所有线程都达到屏障。就像团队聚餐,等所有人都到齐了再一起动筷子。根据Cyclic就可以发现CyclicBarrier可以重复使用。现在有了前面分析ReentrantLock、Semaphore、CountDownLatch的经验,CyclicBarrier也不复杂了,只是这里又引入新的概念:Condition条件队列,这也是最开始我们分析AQS没有讲的东西。
2021-04-21 00:23:33
4668
6

原创 Java并发编程(十五):CountDownLatch源码逐行深度分析
前言CountDownLatch维护了一个计数器(还是是state字段),调用countcountDown方法会将计数器减1,调用await方法会阻塞线程直到计数器变为0。可以用于实现一个线程等待所有子线程任务完成之后再继续执行的逻辑,也可以实现类似CyclicBarrier的功能,达到让多个线程等待同时开始执行某一段逻辑目的。有了前面Semaphore源码分析和ReentrantLock源码分析的基础,再来看CountDownLatch的源码就简单的多了。使用一个线程等待其它线程执行完再继续执行
2021-04-18 18:57:26
4345
7

原创 Java并发编程(十四):Semaphore源码逐行深度分析
使用Semaphore即信号量,可以控制并发访问特定的资源的线程的数量,比如可用于接口请求限流,和ReentrantLock一样依赖AQS实现,使用的话比较简单:Semaphore semaphore = new Semaphore(10);thread-0:semaphore.acquire();//do somethis......semaphore.release();thread-1:semaphore.acquire();//do somethis......semaphor
2021-04-14 21:18:03
4727
5

原创 Java并发编程(十一):ReentrantLock-NonfairSync源码逐行深度分析(下)
前言前面ReentrantLock-NonfairSync源码逐行深度分析(上)和ReentrantLock-NonfairSync源码逐行深度分析(中)两文从源码层面深度分析了NonfairSync的逻辑,有了前面的基础,我们就算是向AQS迈出了第一步,本文针对前面两篇文章做一个系统总结,后面就继续分析依赖AQS的其它工具类。ReentrantLock关键点AQS是抽象类AbstractQueuedSynchronizer的缩写,ReentrantLock中定义了静态内部类Sync继承自AQS,并
2021-04-08 13:24:46
5348
7

原创 可达性分析之三色标记算法详解
二、三色标记在前文中提到了,在CMS的并发清理阶段才产生的垃圾,会被当做浮动垃圾,会留到下一次GC再清理。其实在并发标记阶段,由于用户线程在并发运行,也就可能导致引用关系改变,导致标记结果不准确,从而引发更加严重的问题,这些发生变更的数据会在重新标记阶段被处理,那么会出现什么问题?又是如何处理的呢?CMS算法的基础是通过可达性分析找到存活的对象,然后给存活的对象打个标记,最终在清理的时候,如果一个对象没有任何标记,就表示这个对象不可达,需要被清理。并发标记阶段是从GC Root直接关联的对象开始枚举的
2021-03-30 02:11:16
12346
15

原创 深入OpenJDK源码--你真的了解System.out.println吗?
目录一、前戏二、JVM源码分析三、坑?四、总结一、前戏 可能不少小伙伴习惯在代码中使用sout打印一些信息,就像这样:System.out.println("hello world!") 做为一位资深干码人,本着弘扬党求真务实的精神,必须得来看看这个sout有何玄机~~ 首先看调用就知道,out是System类的一个公共静态成员变量,进入System.java中:public final static PrintStream out = null; 嗯,不止是public,还是fi
2021-03-30 02:10:24
8209
16

原创 深入OpenJDK源码全面理解Java类加载器(上 -- JVM源码篇)
目录前言一、从JDK源码看双亲委派二、使用步骤1.引入库2.读入数据总结前言关于JVM类加载的基础理论知识,请参照《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(上)和《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(下)。一、从JDK源码看双亲委派注:博主是使用的是openjdk8,换了新电脑还没有去编译源码,所以看的是静态代码,关于如何编译和调试源码,网上不少文章都有介绍,这里就不赘述了我们都知道在Java类加载中,除了BootStrap加载器,App和Ext加载
2021-03-19 13:14:48
18316
29

原创 深入OpenJDK源码核心探秘Unsafe(含JNI完整使用流程)
一、介绍在Java中,sun.misc.Unsafe可以认为是用于JDK内部使用的工具类,它将一些需要使用native语言实现的功能通过java方法暴露出来,这些方法比较“危险”,因为它们可以直接修改内存中的值。通常情况下,我们并不能直接在程序中使用Unsafe,Unsafe的构造方法被私有化,语法层面上只能通过其提供的公共静态方法getUnsafe获取Unsafe实例:theUnsafe...
2019-10-19 23:54:52
12413
2

原创 Java并发编程(九):深入OpenJDK源码全面理解 Synchronized
该文章内容较多,发布在gitchat,涉及内容主要包括:一、用法总结 二、类加载器对 class 锁的影响 三、线程的实现 四、基于 monitor 实现的重量级锁 4.1 monitor 4.2 对象内存布局 4.3 monitor 的 C++ 源码实现概览 五、锁优化 5.1 自旋锁 5.2 逃逸分析与锁消除 5.3 锁粗化 5.4 CAS 与轻量级锁...
2019-09-20 22:49:40
28545
13

原创 Lucene检索源码解析(下)
上文已经介绍了检索前的准备工作,本文接着上文的内容,继续剖析检索和打分操作一、获取LeafCollector我们先来看一下IndexSearcher的search方法:protected void search(List<LeafReaderContext> leaves, Weight weight, Collector collector) throws ...
2019-04-26 17:08:58
18639
9

原创 Lucene检索源码解析(上)
有了Lucene得分公式(戳这里看详情)的基础,我们现在先跳过写索引的步骤,直接解析查询这块儿的代码(还是基于5.5.0)。另外由于内容实在太多,所以文章分为上下两部分介绍,上部分主要介绍实际检索前的一些处理,下部分介绍检索和评分。一、场景假设现在已经有多个文档被索引成功,索引目录为:D:\index。我们要对name域(Field)进行查询,代码如下:Path path = Pat...
2019-04-22 18:21:48
12409
3

原创 Lucene打分公式详解(TFIDFSimilarity)
本文章基于Lucene5.5,对其默认使用的打分公式(TFIDFSimilarity)进行解析一、余弦相似度算法由于网络上有很多关于VSM(向量空间模型)的解释,这里就不花费篇章做基本理论的描述了,只总结一下算法即可。给定两个文本,按照余弦相似度算法进行相似度度量一般需要以下步骤:1、提取词条(term)进行向量化。也就是将文本进行分词,每个不同的词都表示为一个term(也就是维度)。...
2019-04-15 21:22:11
13912
5

原创 spring-security框架源码改造:根据接口参数验证权限
一、背景spring-security作为一个权限验证框架,还是很好用的(虽然有点“重”),它能拦截请求,根据请求的路径、配置的权限码和定义的权限验证器进行权限拦截,同时能很方便的和spring、sprign-session等集成。但是我现在有个需求:对于同一个接口的某些参数取不同的值时,可能需要不同的权限验证。比如:/test/set?type=?,当type==1或type==2的时候需要...
2019-03-27 19:02:22
57966
2
原创 SpringCloud系列之版本选择
SpringBoot版本 进入Spring官网,查看当前SpringBoot版本: 当前最新版本是2.5.4 GA,如果单纯使用SpringBoot框架,那么选择2.5.4 GA就行。GA即General Availability,表示官方推荐使用的稳定版本,和release版本一个意思~关于SpringBoot的更多版本可以在https://github.com/spring-projects/spring-boot/wiki#release-notes找到。SpringCloud
2021-09-09 15:53:27
10301
原创 Spring源码分析系列-循环依赖和三级缓存
循环依赖循环依赖(区别于dependsOn)的现象很简单,A对象在创建的时候依赖于B对象,而B对象在创建的时候依赖于A对象
2021-05-25 22:13:41
3657
9
原创 Spring源码分析系列-Bean的生命周期(总结篇)
ApplicationContext和BeanFactoryBeanFactory是Spring中的顶层接口,只负责管理bean,BeanDefinitionReader和BeanDefinitionRegistryBean的生命周期一个被Spring管理的Bean,首先被加载之后首先会被包装成一个BeanDefinition,BeanDefinition代表了一个Spring中Bean的各种基础属性,比如作用域、是否懒加载、所属类class、自动装配类型等等。类被包装成BeanDefinitio
2021-05-20 00:25:23
2467
10
原创 Java并发编程(二十):FutureTask源码分析
使用 FutureTask<String> futureTask = new FutureTask(() -> "success"); new Thread(futureTask).start(); futureTask.get();源码分析FutureTask提供了两个构造方法,分别是传入一个Callable,和传入一个Runnable和返回值result。如果传入的是Runnable和返回值,那么会通过适配器RunnableAdap
2021-05-11 01:07:16
2852
1
原创 Java并发编程(十七):Atomic、LongAdder等总结
一、前言JUC是java.util.concurrent包的简称,该包中提供了Java并发编程中常用的工具类,从Java5.0开始提供。像我们前面总结的volatile和synchronized关键字,虽然使用起来很方便,但是从功能来说较为简单,很多并发需求它们并不能够直接满足。而通过JUC,我们能很方便地实现更加复杂的并发控制逻辑。从这边博文开始,我们会对整个JUC进行全面的总结,每一个工具...
2021-04-27 01:28:20
3899
原创 MySQL--join算法(Nested-Loop Join、Block Nested-Loop Join)
MySQL的一个连接查询涉及到两张表的关联,既然涉及到两张表的关联那么就需要一定的算法来组织数据。关联的两张表,一个叫做**驱动表**,一个叫做**被驱动表**。
2021-04-15 00:46:44
6729
3
原创 MySQL--count(*)、count(1)、count(id)、count(field)比较
注:环境为MySQL 7 InnoDB测试首先创建一个测试表:CREATE TABLE `test_table` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `num` bigint(20) DEFAULT NULL, PRIMARY KEY (`id`), KEY `I1` (`num`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;test_table表中有两个索引,分别是.
2021-04-14 00:23:11
2105
3
原创 SPI之ServiceLoader应用与源码分析
在SPI的应用中,Java支持对外开放了一些服务接口(或者抽象类,也可以使用普通类,但是不建议),但是不提供具体的实现,这些实现可以由第三方提供,支持用户以扩展的方式集成到系统中。那么这就需要一种服务发现机制。也就是根据一定的规则到指定的位置找到指定服务的配置文件,然后找到实现类。ServiceLoader便提供了这么一个手段,能够在系统中"指定"位置(META-INF/services)的"指定"文件(文件名是服务全限定名称)中寻找指定服务的三方实现。
2021-04-12 22:38:46
4707
1
原创 Java并发编程(十三):ReentrantLock-tryLock(long timeout, TimeUnit unit)源码分析
在前文ReentrantLock-NonfairSync源码逐行深度分析中,已经分析了AQS加解锁,阻塞唤醒与CLH队列的使用,这里主要看看带超时时间的tryLock实现。在ReentrantLock的tryLock(timeout)方法中调用的是sync的tryAcquireNanos:public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return
2021-04-12 22:02:20
2102
原创 MySQL查询当前事务ID TRX_ID
#begin不会立即分配TRX_IDbegin;#触发分配TRX_IDselect * from t;#指定TRX_MYSQL_THREAD_ID=当前CONNECTION_ID,表示查询当前连接select TRX_ID from INFORMATION_SCHEMA.INNODB_TRX where TRX_MYSQL_THREAD_ID = CONNECTION_ID();commit;
2021-04-12 01:12:20
5560
4
原创 MySQL总结--MVCC(read view和undo log)
MVCC(Multi-Version Concurrency Control),即多版本并发控制,数据库通过它能够做到遇到并发读写的时候,在不加锁的前提下实现安全的并发读操作,是一种乐观锁的实现方式,能大大提高数据库的并发性能。
2021-04-12 00:57:59
7451
9
原创 MySQL事务和锁总结
- 原子性(Atomicity) :一个事务中的操作,要么全部成功,要么全部失败,可以通过undo log回滚。- 一致性(Consistent) :在事务的前后,数据都必须保持一致状态。如果事务在执行过程中被中断,导致一部分更新已经入库,但是这部分数据没有回滚,就出现了数据不一致。可以简单理解为和原子性类似,只是原子性关注的是行为,而一致性关注的是数据。
2021-04-11 01:34:08
2541
原创 Jetty对ServletContainerInitializer的支持与Spring的应用
关于ServletContainerInitializer和@HandlesTypesServletContainerInitializer是一个定义在javax.servlet包中的接口,根据servlet规范,框架提供的 ServletContainerInitializer实现必须绑定在 jar包的META-INF/services目录中的一个叫做 javax.servlet.ServletContainerInitializer的文件,在其中指定ServletContainerInitialize
2021-04-09 22:30:42
3018
原创 Java并发编程(十二):ReentrantLock-FairSync源码分析(hasQueuedPredecessors)
前言有了前面ReentrantLock-NonfairSync源码逐行深度分析的基础,理解公平锁FairSync的实现就很简单了。ReentrantLock的默认构造函数创建的是非公平锁,同时提供了布尔类型的有参构造函数,true表示创建公平锁。public ReentrantLock() { sync = new NonfairSync();}public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new No
2021-04-08 22:23:29
4596
1
原创 Java并发编程(十):ReentrantLock-NonfairSync源码逐行深度分析(中)
,同样在AQS中找到该方法的实现:final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { //标识是否被中断 boolean interrupted = false; //死循环 for (;;) { //获取node节点的前驱节点
2021-04-07 23:57:09
6233
7
原创 Java并发编程(九):ReentrantLock-NonfairSync源码逐行深度分析(上)
CAS 修改state加锁自旋加锁park阻塞线程队列保存阻塞的线程:双向链表实现队列,为了防止每次判空,会有一个空的头结点。CAS保证入队必须成功unpark或interrupt唤醒
2021-04-05 01:18:04
3830
4
原创 MySQL--buffer pool、redo log、undo log、binlog
由于磁盘随机读写的效率很低,MySQL为了提供性能,读写不是直接操作的磁盘文件,而是在内存中开辟了一个叫做buffer pool的缓存区域,更新数据的时候会优先更新到Buffer Pool,之后再由I/O线程写入磁盘。同时为了保证MySQL宕机不丢失buffer pool中的数据,还引入了一个 叫做redo log的日志文件 。另外还有用于备份磁盘数据的bin log,用于事务回滚和MVCC的undo log等。对于日志文件则采取顺序读写的方式提高效率。2.12.2
2021-04-03 23:37:30
6986
8
原创 Java实用工具之StringJoiner
背景 在平时的业务开发中,我们可能会遇到字符串列表根据分隔符进行拼接的需求。比如:输入:数组:[“a”,“b”,“c”]分隔符:","输出:“a,b,c”处理 通常我们可以使用StringBuilder根据下标位置决定是否需要添加分隔符以达到目的,比如:public static void main(String[] args) { StringBuilder sb = new StringBuilder(); String[] string
2021-04-02 00:19:19
1360
原创 多类加载器环境下使用synchronized的注意事项
如果使用synchronized对obj.getClass()加锁,锁对象就是Class,那么对于这个Class下的所有实例对象访问都能达到同步控制的目的。比如以下代码:public class JavaMain { public void run() { synchronized (this.getClass()) { int i = 0; while (i++ < 10) { try {
2021-03-31 02:42:24
2356
4
原创 垃圾收集之Remember Set(CardTable)
JVM为了更好的管理内存,提高GC效率,一般都会对内存进行划分,比如经典的分代收集,G1推出的Region等。而Java中的垃圾收集基本都基于可达性分析算法,这就涉及到对象枚举遍历和标记的过程。在做Minor GC的时候会对年轻代进行根节点枚举,但是如果年轻代中的一些对象被老年代引用着,那么在做年轻代可达性分析的时候就会遇到很大的阻碍,总不能在Minor GC的时候还去扫描老年代吧?这种跨代引用的问题抛开出现频率,它总是会存在,而且在G1这种多Region结构中更加突出(包括ZGC、Shenandoah
2021-03-31 01:40:11
4433
3
原创 深入OpenJDK源码-偏向锁的延时生效如何实现的
关于偏向锁,包括撤销和重偏向在前面已经结合源码分析过了,这里就不再赘述,主要看看延时生效的问题。另外,本文贴出的源码大多都只保留了当前关注的逻辑。 我们知道虚拟机为我们提供了参数- XX:+UseBiasedLocking以开启或者关闭偏向锁优化(默认开启),但是偏向锁的启用有个默认的延时时间,可以通过参数- XX:BiasedLockingStartupDelay设置,默认为4秒,可以在globals.hpp中找到默认值设置: product(intx, BiasedLockingStartu.
2021-03-30 23:45:49
5787
4
原创 一个Spring+SpringMVC动态代理不生效的问题
有一个使用SSM搭建的服务,之前由于功能扩展需要引入AOP,但是测试的时候AOP却无法生效,通过检查最终确认了问题,还顺带送了另一个问题~
2021-03-30 02:08:27
1906
原创 垃圾收集器总结--CMS垃圾收集器
目录一、CMS1.1 概述1.2 内存碎片1.3 浮动垃圾1.4 空间预留1.4 Promotion Failed和Concurrent Mode Failure1.5 常用参数二、总结一、CMS1.1 概述 CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器,其主要优点就是并发收集、低停顿。适合重视服务响应速度的应用的服务器,基于标记-清除算法,用于老年代。它是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次基本上实现了让垃圾收集线程与
2021-03-28 22:49:46
3182
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人