自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(54)
  • 收藏
  • 关注

原创 16、CPU缓存架构

CPU高速缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。缓存一致性协议会通过处理器之间的通信,确保在一个处理器修改了某个数据后,其他处理器缓存中的该数据会被更新或者失效,从而保证在多个处理器同时对同一个数据进行操作时,它们所看到的数据始终是一致的。当特定数据被多个缓存共享时,处理器修改了共享数据的值,更改必须传播到所有其他具有该数据副本的缓存中。

2024-08-26 15:29:36 2340

原创 15、深入解析并发原子性、可见性、有序性与JMM内存模型

JSR-133使用happens-before的概念来指定两个操作之间的执行顺序。由于这两个操作可以在一个线程之内,也可以在不同的线程之内。因此,JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证。如果一个操作happens-before 另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。这是JMM对程序员的承诺, 注意,这只是JMM向程序员做出的保证。

2024-08-26 15:27:06 1413

原创 14、深入解析ForkJoinPool线程池

归并排序(Merge Sort)是一种基于分治思想的排序算法。归并排序的基本思想是将一个大数组分成两个相等大小的子数组,对每个子数组分别进行排序,然后将两个子数组合并成一个有序的大数组。因为常常使用递归实现(由先拆分后合并的性质决定的),所以我们称其为归并排序。将数组分成两个子数组对每个子数组进行排序合并两个有序的子数组归并排序的时间复杂度为O(nlogn),空间复杂度为O(n),其中n为数组的长度。

2024-08-25 17:44:15 1213

原创 13.深入解析ThreadPoolExecutor线程池

线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如Tomcat。线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的整体性能。线程池维护多个线程,等待监督管理者分配可并发执行的任务。这种做法,一方面避免了处理任务时创建销毁线程开销的代价,另一方面避免了线程数量膨胀导致的过分调度问题,保证了对内核的充分利用。线程池有如下的优势降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。

2024-08-25 17:42:16 1016

原创 12、深入解析阻塞队列BlockingQueue

是限定在一端进行插入,另一端进行删除的特殊线性表。先进先出(FIFO)线性表。允许出队的一端称为队头,允许入队的一端称为队尾。

2024-08-24 11:42:24 871

原创 11、深入解析JUC包下的并发集合

原理:基于CopyOnWriteArrayList实现,其唯一的不同是在add时调用的是CopyOnWriteArrayList的addIfAbsent方法,其遍历当前Object数组,如Object数组中已有了当前元素,则直接返回,如果没有则放入Object数组的尾部,并返回。:HashMap线程不安全!原理:利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合,在新的集合上面修改,然后将新集合赋值给旧的引用,并通过volatile 保证其可见性,当然写操作的锁是必不可少的了。

2024-08-24 11:34:23 633

原创 10、深入理解AQS之循环栅栏CyclicBarrier

CyclicBarrier基于 ReentrantLock + ConditionObject实现,CyclicBarrier的构造函数中必须指定parties,同时对象generation,内部持有布尔型属性表示当前CyclicBarrier执行过程中是否有超时、异常、中断的情况。parties是初始待执行线程数,在构造函数中会将parties赋给计数值count,每当一个线程执行await(),count就会减1。

2024-08-23 11:15:25 956

原创 9、深入理解AQS之闭锁CountDownLatch

CountDownLatch让一个或多个线程等待其他线程执行完成后再执行。在创建CountDownLatch对象时,必须指定线程数count,每当一个线程执行完成调用countDown()方法,线程数count减1,当count减到0时,await()方法就不再阻塞。

2024-08-23 11:14:16 600

原创 8、深入理解AQS之共享锁Semaphore

公平锁,优先判断等待队列中是否有挂起的线程,如果有,则将当前线程添加到等待队列中,等待唤醒后抢夺信号量;非公平锁,不管等待队列中是否有挂起线程,优先尝试获取信号量,获取失败,将当前线程添加到等待队列。

2024-08-22 15:21:00 506

原创 7、深入理解AQS之独占锁ReentrantLock

java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如等待队列、条件队列、独占获取、共享获取等,而这些行为的抽象就是基于AbstractQueuedSynchronizer(简称AQS)实现的,AQS是一个抽象同步框架,可以用来实现一个依赖状态的同步器。JDK中提供的大多数的同步器如Lock, Latch, Barrier等,都是基于AQS框架来实现的一般是通过一个内部类Sync继承 AQS将同步器所有调用都映射到Sync对应的方法阻塞等待队列。

2024-08-22 15:19:47 1062

原创 6、JUC并发同步工具类应用与实战

ReentrantLock的应用场景主要体现在多线程环境下对共享资源的独占式访问,以保证数据的一致性和安全性。ReentrantLock具体应用场景如下:1.解决多线程竞争资源的问题,例如多个线程同时对同一个数据库进行写操作,可以使用ReentrantLock保证每次只有一个线程能够写入。2.实现多线程任务的顺序执行,例如在一个线程执行完某个任务后,再让另一个线程执行任务。3.实现多线程等待/通知机制,例如在某个线程执行完某个任务后,通知其他线程继续执行任务。

2024-08-21 10:08:55 1942

原创 5、并发锁机制之synchronized

批量重偏向和批量撤销是针对类的优化,和对象无关。偏向锁重偏向一次之后不可再次重偏向。当某个类已经触发批量撤销机制后,JVM会默认当前类产生了严重的问题,剥夺了该类的新实例对象使用偏向锁的权利。

2024-08-21 10:07:21 1025

原创 4、CAS和Atomic详解

CAS(Compare And Swap,比较与交换),是非阻塞同步的实现原理,它是CPU硬件层面的一种指令,从CPU层面能保证"比较与交换"两个操作的原子性。CAS指令操作包括三个参数:内存值(内存地址值)V、预期值E、新值N,当CAS指令执行时,当且仅当预期值E和内存值V相同时,才更新内存值为N,否则就不执行更新,无论更新与否都会返回否会返回旧的内存值V,上述的处理过程是一个原子操作。// 内存中当前的值/*** @param expectedValue 期望值。

2024-08-20 09:48:27 1052

原创 3、ThreadLocal详解

Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get和set方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程上下文。特性:1.线程安全: 在多线程并发的场景下保证线程安全;2.传递数据: 我们可以通过ThreadLocal在同一线程,不同组件中传递公共变量;3.线程隔离: 每个线程的变量都是独立的,不会互相影响;

2024-08-20 09:47:22 921

原创 2、Future与CompletableFuture实战

直接继承Thread或者实现Runnable接口都可以创建线程,但是这两种方法都有一个问题就是:没有返回值,也就是不能获取执行完的结果。因此java1.5就提供了Callable接口来实现这一场景,而Future和FutureTask就可以和Callable接口配合起来使用。不能返回一个返回值;不能抛出checked Exception;Callable的call方法可以有返回值,可以声明抛出异常。

2024-08-19 14:06:30 852 1

原创 1、从0开始深入理解并发、线程与等待通知机制

线程之间相互配合,完成某项工作,比如:一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。join可以理解成是线程合并,当在一个线程调用另一个线程的join方法时,当前线程阻塞等待被调用join方法的线程执行完毕才能继续执行,所以join的好处能够保证线程的执行顺序,但是如果调用线程的join方法其实已经失去了并行的意义,虽然存在多个线程,但是本质上还是串行的,最后join的实现其实是基于等待通知机制的。

2024-08-19 14:02:55 1022

原创 16、Spring~配置类

Spring容器在启动过程中,在BeanFactory创建之后,会执行BeanFactoryPostProcessors,这里会拿到之前Spring容器自己设置的ConfigurationClassPostProcessor,Spring容器详细的启动过程请移步至《doProcessConfigurationClass()方法详解。processConfigurationClass()方法详解。parse()方法,有几个重载方法,不同参数处理逻辑都是调用。通过上述代码,可以看到,这里会调用。

2024-06-26 21:22:32 1162

原创 15、Spring~容器启动过程

15、Spring~容器启动过程容器启动过程AnnotationConfigApplicationContext类的四个构造器:启动过程详解无参构造方法refresh()方法prepareRefresh()方法prepareBeanFactory()方法invokeBeanFactoryPostProcessors()方法registerBeanPostProcessors()方法finishBeanFactoryInitialization()方法GenericApplicationContext对象详解

2024-06-26 21:21:50 1337 1

原创 14、Spring之Bean生命周期~推断构造方法

这里我们可以看到,最终会调用ConstructorResolver类的instantiateUsingFactoryMethod()方法,我们详细分析一下ConstructorResolver类的instantiateUsingFactoryMethod()方法。通过上述代码,我们可以看到,这里会调用ConstructorResolver类的autowireConstructor()方法,接下来,我们详细分析ConstructorResolver类的autowireConstructor()方法。

2024-06-21 14:05:33 1105

原创 15、Spring之Bean生命周期~总结

扫描这一步扫描将带@Component注解的类扫描成BeanDefinition相关博客《Spring之Bean生命周期~扫描合并BeanDefinition类直接存在继承关系,扫描到的BeanDefinition也需要进行继承;相关博客《Spring之Bean生命周期~合并BeanDefinition获取Bean这一步为什么是获取Bean不是创建Bean,Spring容器中大多数Bean对象都是单例的,有单例池的存在,单例池中没有Bean才会去创建Bean;实例化前实例化。

2024-06-21 14:05:09 339

原创 13、Spring之Bean生命周期~循环依赖

AutowiredBeanOne Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。AutowiredBeanTwo Bean对象。

2024-06-18 11:34:23 712

原创 12、Spring之Bean生命周期~依赖注入(3)

通过上述代码,我们可以看到,不管是属性还是方法都会调用getResourceToInject()方法查找属性的值,我们这里可以看到,InjectedElement类是一个抽象类,看他的子类会发现,ResourceElement继承啦InjectedElement类,或者在查找注入点时,最后我们可以看到属性或者方法参数被封装成ResourceElement对象放入啦缓存。这里还有一个有意思的判断,判断啦方法参数必须是一个,不能没有参数,也不能有一个以上的参数,否则会报错;getResource()方法详解。

2024-06-18 11:33:34 675

原创 11、Spring之Bean生命周期~依赖注入(2)

11、Spring之Bean生命周期~依赖注入(2)依赖注入查找注入点对注入点进行赋值InjectionMetadata.inject()方法AutowiredFieldElement.inject()方法resolveFieldValue()方法resolveDependency方法createOptionalDependency()方法doResolveDependency()方法determineAutowireCandidate()方法resolveMultipleBeans()方法findAuto

2024-06-17 09:11:23 2503 3

原创 10、Spring之Bean生命周期~依赖注入(1)

这里并没有校验属性是不是被static修饰的,因为@Bean(autowire = Autowire.BY_NAME)已经是不推荐的方式,这里没有深入研究,欢迎知道的大佬留言!@Bean(autowire = Autowire.BY_NAME)方式的依赖注入,如果想了解其他方式的依赖注入请移步至《registerDependentBean()方法详解。autowireByName()方法详解。autowireByType()方法详解。

2024-06-17 09:10:57 828

原创 9、Spring之Bean生命周期~依赖注入(总)

通过XML中定义Bean时,可手动注入。从类型角度区分,分两种:手动和自动。

2024-06-16 16:04:55 736

原创 8、Spring之Bean生命周期~销毁

spring容器在正常关闭的时候会销毁Bean对象,比如上述代码中,执行close方法时,容器关闭,销毁单例的Bean对象;通过上述代码我们可以看到,如果给BeanDefinition设置指定的销毁方法或者把销毁方法设置成(inferred),spring在销毁bean的时候会去找bean中的close方法和shutdown方法;inferDestroyMethodIfNecessary()方法详解。requiresDestruction()方法详解。hasDestroyMethod()方法详解。

2024-06-16 11:53:23 404

原创 7、Spring之Bean生命周期~初始化

这里可以看到,首先会判断当前Bean对象是否实现了InitializingBean接口,如果实现了就调用它的afterPropertiesSet()方法,然后判断BeanDefinition中是否指定初始化方法,如果指定啦初始化方法且不是afterPropertiesSet()方法的话,会调用BeanDefinition指定的初始化方法;applyBeanPostProcessorsBeforeInitialization()方法详解。invokeAwareMethods()方法详解。

2024-06-10 17:18:45 905 1

原创 6、Spring之Bean生命周期~创建Bean(2)

【代码】6、Spring之Bean生命周期~创建Bean(2)

2024-06-10 17:18:17 813

原创 5、Spring之Bean生命周期~创建Bean(1)

Spring Bean的生命周期首先会经过扫描,然后回经过合并,合并之后就会通过getBean()方法去获取bean,getBean()方法大致逻辑,先根据判断是单例bean还是原型bean,原型bean直接创建,单例bean会判断单例池中有没有,没有的话调用createBean()方法。如果实例化前这一步有返回值,会直接返回,不走后续的实例化、依赖注入、初始化前,直接跳到初始化这一步,执行AOP操作;resolveBeforeInstantiation()方法详解。通过上述代码,我们就可以看到。

2024-06-09 16:46:34 723

原创 4、Spring之Bean生命周期~获取Bean

Spring Bean的生命周期首先会经过扫描,然后回经过合并,合并之后就会通过getBean()方法去获取bean,getBean()方法大致逻辑,先根据判断是单例bean还是原型bean,原型bean直接创建,单例bean会判断单例池中有没有,没有的话再去创建。通过canonicalName()方法我们可以看到,会不断地从aliasMap中回去,直到获取到的是null,说明是真正的BeanName;这里我们可以看到如果BeanName是以&开头的话,会截取掉开头所有的&;此方法涉及到解决循环依赖。

2024-06-09 16:45:21 1118

原创 3、Spring之Bean生命周期~合并BeanDefinition

spring通过扫描,将class文件封装成BeanDefinition之后,并不能直接拿BeanDefinition去创建Bean对象,中间还需要经过一系列的合并和判断,废话不多说,直接上代码;通过上述代码我们可以看到首先回去mergedBeanDefinitions缓存中判断,这个BeanDefinitions是否已经合并过,如果合并过直接拿缓存中的对象,缓存中没有的话,调用。合并beanDefinition和java中的类继承一样,子类有的用子类,子类没有的用父类;

2024-06-07 14:20:43 454

原创 2、Spring之Bean生命周期~扫描

不管那种方式都需要指定spring容器的扫描路径,xml文件通过 <context:component-scan /> 标签设置扫描路径,配置类通过 @ComponentScan 注解设置扫描路径,spring容器在拿到扫描路径之后就会对配置的路径进行挨个扫描,如果符合bean的要求,就会把他封装成一个BeanDefinition。这是只是大致过一个spring容器的创建,具体详细的创建步骤并不会展开细说,只说和bean生命周期有关的部分;findCandidateComponents方法详解。

2024-06-07 14:20:24 1230

原创 3、Tomcat类加载机制

Spring 作为共享的第三方 JAR 包,它本身是由 SharedClassLoader 来加载的,Spring 又要去加载业务类,按照前面那条规则,加载 Spring 的类加载器也会用来加载业务类,但是业务类在 Web 应用目录下,不在 SharedClassLoader 的加载路径下,这该怎么办呢?这种类加载机制其实就是双亲委派机制,加载某个类时会先委托父加载器寻找目标类,找不到再 委托上层父加载器加载,如果所有父加载器在自己的加载类路径下都找不到目标类,则在自己的类加载路径中查找并载入目标类。

2024-06-04 19:50:52 1002

原创 1、Spring之底层架构核心概念

bean一定是一个对象。在Spring的源码实现中,当我们new一个ApplicationContext时,其底层会new一个BeanFactory出来,当使用ApplicationContext的某些方法时,比如getBean(),底层调用的是BeanFactory的getBean()方法。为什么要使用ASM技术,Spring启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的类是非常多的,那如果在Spring启动时就把这些类全部加载进JVM了,这样不太好,所以使用了ASM技术。

2024-06-04 19:50:25 1271

原创 2、Tomcat 线程模型详解

那么,子 reactor 会监听客户端连接上的后续事件,有读写事件发生时,它会让在同一个线程中的 handler 读取请求和返回结果,而和单 reactor 多线程类似,具体业务处理,它还是会让线程池中的 worker 线程处理。你会看到 Tomcat 中的各种连接器,展开“http-nio-8080”,你会看到这个连接器上的统计信息,其中 maxTime 表示最长的响应时间,processingTime 表示平均响应时间,requestCount 表示吞吐量,errorCount 就是错误数。

2024-06-03 15:30:03 2386

原创 1、Tomcat整体架构

官方文档Tomcat是Apache Software Foundation(Apache软件基金会)开发的一款开源的Java Servlet容器。它是一种Web服务器,用于在服务器端运行Java Servlet和JavaServer Pages (JSP)技术。它可以为Java Web应用程序提供运行环境,并通过HTTP协议处理客户端请求。Tomcat也支持多种Web应用程序开发技术,例如JavaServer Faces (JSF)、Java Persistence API (JPA)等。总的来说,

2024-06-03 15:29:38 2777

原创 7、Innodb底层原理

我们知道由于MySQL是开源的,他有非常多种类的客户端:navicat,mysql front,jdbc,SQLyog等非常丰富的客户端,包括各种编程语言实现的客户端连接程序,这些客户端要向mysql发起通信都必须先跟Server端建立通信连接,而建立连接的工作就是有连接器完成的。查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。开始执行的时候,要先判断一下我们所登录的用户对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如果有权限,就打开表继续执行。

2024-05-31 15:03:37 648

原创 6、MySQL之MVCC

MVCC机制的实现就是通过read-view机制与undo版本链比对机制,使得不同的事务会根据数据版本链对比规则读取同一条数据在版本链上的不同版本数据。

2024-05-31 15:03:06 971

原创 5、Mysql事务隔离级别与锁机制

我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题。接下来,我们会深入讲解这些机制,让大家彻底理解数据库内部的执行原理。锁是计算机协调多个进程或线程并发访问某一资源的机制。

2024-05-25 19:22:43 1041

原创 4、SQL性能调优

小于、 > 大于、 <=、>= 这些,mysql内部优化器会根据检索比例、表大小等多个因素整体评估是否使用索引。转化为日期范围查询,有可能会走索引(MySQL版本8.0):可以将大的范围拆分成多个小范围。mysql5.7中测试结果。mysql5.7中测试结果。mysql5.7中测试结果。mysql8中测试结果。mysql8中测试结果。mysql8中测试结果。

2024-05-24 15:25:37 763 1

空空如也

空空如也

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

TA关注的人

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