SPI

Java的SPISPI全称为Service Provider Interface,是jdk内置的一种服务提供发现机制。简单来说,它就是一种动态替换发现的机制。 SPI规定,所有要预先声明的类都应该放在META-INF/services中。配置的文件名是接口/抽象类的全限定名,文件内容是抽象类的子类或接口的实现类的全限定类名,如果有多个,借助换行符,...

阅读全文

Spring循环依赖

前置知识 Spring的依赖注入方式,我们分为setter注入和构造器注入。那么Spring可以解决掉setter类型的依赖注入,构造器形式的是不可以的。 Spring的单例和多例模式,多例模式下的依赖注入也是解决不掉的。所以我们关注的范围为单例模式下setter注入形式的循环依赖的解决方案。 SpringBean的生命周期我们可以概括为实例化、属性赋值、初...

阅读全文

SpringBoot如何启动IOC容器

main方法进入12345678@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, a...

阅读全文

JVM垃圾回收

如何判断对象是否存活垃圾收集器在对堆进行回收前,首先就是需要确定哪些对象还”存活”,哪些已经”死去”(即不可能再被任何途径使用的对象),大致上来说有两种算法: 1)引用计数算法 这也是很多教科书中判断对象是否存活的算法: 给对象添加一个引用计数器,当该对象被引用时,计数器加1;当引用失效时,计数器减1,任何时刻计数器为0的对象就是不可能再被使用的。该算法实现...

阅读全文

JVM运行时区域

JVM运行时内存区域我们以HotSpot虚拟机为前提下展开,因为目前使用最多的还是HotSpot虚拟机。 Java虚拟机在执行Java程序时,会将分配给JVM的内存划分为几个不同的区域。有些区域在JVM启动之后就存在,直到关闭JVM进程;有些区域则依赖于用户线程,随着用户线程的生命周期一同创建和销毁。 从Java1.8开始,JVM内存区域划分如图所示,从图中...

阅读全文

线程池的基本原理

什么是线程池线程池其实是一种池化的技术的实现,池化技术的核心思想其实就是实现资源的一个复用,避免资源的重复创建和销毁带来的性能开销。在线程池中,线程池可以管理一堆线程,让线程执行完任务之后不会进行销毁,而是继续去处理其它线程已经提交的任务。 使用线程池的好处: 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度。当任务到达时...

阅读全文

ThreadLocal

ThreadLocal概念ThreadLocal,即线程变量,是以一个ThreadLocal对象为key、任意对象为值的存储结构。这个结构被附带在线程上,也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。 ThreadLocal使用场景场景1,ThreadLocal 用作保存每个线程独享的对象,为每个线程都创建一个副本,这...

阅读全文

Synchronized的实现原理

概念及用法在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着JDK的升级迭代,对其进行了各种优化之后,有些情况下它就并不那么重了。 先来看下利用Synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现有三种使用方式: 对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前...

阅读全文

JMM内存模型与volatile关键字

前言CPU Cache模型在现在的计算机中,所有的运算操作都是由CPU的寄存器完成的,而过程涉及数据的存取都需要主存内存的确认。但是主内存由于制造工艺和成本的限制,在访问速度上还是大大落后于不断发展的CPU的处理速度,他们的差距能够达到成千上万倍。于是,就有了在CPU和主内存之间增加缓存的设计。程序在运行的过程中,会将运算所需要的数据从主存复制一份到CPU ...

阅读全文

ConcurrentHashMap源码解析

前言当我们碰到线程不安全场景下,需要使用 Map 的时候,我们第一个想到的 API 估计就是 ConcurrentHashMap,ConcurrentHashMap 内部封装了锁和各种数据结构来保证访问 Map 是线程安全的,接下来我们一一来看下,和 HashMap 相比,多了哪些数据结构,又是如何保证线程安全的。 类注释我们从类注释上大概可以得到如下信息:...

阅读全文