
Java
文章平均质量分 90
java
不爱学习的灰灰
这个作者很懒,什么都没留下…
展开
-
【springboot】启动流程之starting
一、概述starting作为springboot启动流程中最早的一个生命周期,过程相对比较简洁因此源码也相对较少,比较适合入门者的源码研究。在此阶段中spring主要完成了日志系统的选择、后台预加载等动作。二、SpringApplicationRunListener和ApplicationListener在上一篇文章中的最后一小节,我们可以发现在进行第一个生命周期回调(也就是starting)前,spring先通过getRunListeners方法获取了一个SpringApplicationRunLi原创 2020-08-20 14:26:07 · 849 阅读 · 0 评论 -
【springboot】初识启动流程
一、spring是如何启动的springboot的启动代码非常简洁优雅,通常只需一个注解@SpringBootApplication和一行代码就能将应用启动起来:SpringApplication.run(App.class, args);主线程执行完后,由于有其他非daemon线程还存活着(例如tomcat的线程),所以整个应用在没有发生重启的情况下能实现7*24不间断运行。这一个run方法最后进入源码其实就是这一行代码new SpringApplication(primarySources).run(原创 2020-08-18 15:22:03 · 217 阅读 · 0 评论 -
【集合】ArrayList
一、概述ArrayList是一个用来顺序存储元素的集合,它是有序且可以随机访问的。正如它的名字所示,它的底层数据结构就是用数组实现的。那为什么不直接用数组存储元素呢?因为ArrayList提供了一系列人性化的API,迭代器以及自动扩容机制,使你不必关心数组元素的迁移变动。有几个关键的成员变量需要我们重点关注一下:elementData:一个对象数组,ArrayList用于存储元素的关键数据结构size:elementData数组中已经存储的元素数量modCount:ArrayList的修改次数,详原创 2020-07-31 19:59:59 · 315 阅读 · 0 评论 -
【集合】HashMap(JDK8)
迭代器public void testIter() { List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object o = iterator.next();原创 2020-07-29 20:56:04 · 203 阅读 · 0 评论 -
【多线程与并发】ThreadLocal与强软弱虚引用
ThreadLocal:线程本地变量,用于保存线程私有的变量,保证多线程之间的数据隔离性。为什么不用方法内的局部变量?局部变量作用域为当前方法,而ThreadLocal可以跨方法获取ThreadLocalMap是一个entry数组,存储键值对(entry的key引用是弱引用),其中key是ThreadLocal对象,value是一个object对象。每个ThreadLocal对象会生成一个threadLocalHashCode,用于决定它在ThreadLocalMap中的位置。当hash冲突时采取线性查原创 2020-07-22 12:06:04 · 343 阅读 · 0 评论 -
【maven】常用配置片段
一、默认开启jdk1.8<!-- 在settings.xml中配置 --><profiles> <profile> <id>jdk-1.8</id> <activation> <!-- 默认每个maven工程都加入这个配置 --> <activeByDefault>true</activeByDefault>原创 2020-07-18 13:14:58 · 165 阅读 · 0 评论 -
【多线程与并发】线程池
一、概念1. 什么是线程池线程池顾名思义是一个统一管理线程的工具,它如同一个池子一般装载了创建出来的线程,并掌控着它们的生命周期和调度工作,从而起到复用线程的作用。这种池化的思想还常常用于数据库连接。在JDK中线程池对应的类为java.util.concurrent.ThreadPoolExecutor2. 为什么需要线程池降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗(创建销毁线程需要系统调用)。提高响应速度:任务到达时,无需等待线程创建即可立即执行。提高线程的原创 2020-06-28 20:46:51 · 255 阅读 · 0 评论 -
【多线程与并发】ReentrantLock与AQS
一、前言ReentrantLock(以下简称RL)是JDK5之后推出的互斥锁,实现了java.util.concurrent.locks.Lock接口,功能和synchronized关键字很相似,但是写法上有区别,而且提供了几个更加灵活的API:等待可中断:tryLock(long timeout, TimeUnit unit)以及lockInterruptibly()能够响应中断公平锁:RL构造方法提供了一个布尔选项打开公平锁,不过会使性能急剧下降多条件:newCondition()能够使线程等原创 2020-06-03 21:59:27 · 448 阅读 · 0 评论 -
【多线程与并发】CAS与原子类
一、概念CAS(compare and swap/set)称为比较并交换或者自旋锁,是一种基于冲突检测的乐观锁,也称之非阻塞同步。换句话说就是不管三七二十一我先尝试操作,要是没有其他线程和我冲突那我就操作成功了,否则我就进行不断地重试直到没有冲突产生,期间不会去阻塞其他线程。这样会产生一个问题那就是怎么保证我检测冲突和操作能够具有连贯的原子性?总不能我冲突检测完成了,但是在我操作的时候其他线程已经把这个值改了。但如果我加锁的话,那不还是阻塞同步(悲观锁)了吗?因此这个CAS操作只能够通过硬件指令集来完原创 2020-05-25 21:44:06 · 247 阅读 · 0 评论 -
【多线程与并发】synchronized同步锁
一、概念synchronized为java内置的关键字,用于保证一组代码的原子性以及该代码中共享变量的可见性(happens-before原则的Monitor Lock Rule),同时由于as-if-serial语义(不管怎么重排序,单线程下的执行结果不能被改变),该关键字又可以说是有序性的,所以synchronized在解决并发问题上可以说是“万能”的。从并发策略上来看,这种互斥同步(阻塞同步)锁是一种悲观锁。那么如何使用呢?可以将该关键字加在方法(构造方法和接口方法例外)上,也可以使用synchr原创 2020-05-24 17:17:17 · 371 阅读 · 0 评论 -
【多线程与并发】JMM与volatile
一、java内存模型每个线程访问共享变量时(如静态变量、单例中的成员变量等),会将该变量从主内存中存入一个副本到自己的工作内存。线程对这些共享变量的读写只会在工作内存中进行,且线程间不能访问对方的工作内存,共享变量的值传递需要通过主内存完成。这种内存模型的主要来源是计算机硬件模型,线程是cpu的基本调度单位,线程的工作内存就是cpu对应的高速缓存cache。那么为什么要用这种模型呢?原因还是效率问题:CPU速率>Cache速率>主内存速率>io外设速率。两者关系见下图二、jvm内存原创 2020-05-23 16:21:58 · 200 阅读 · 0 评论 -
【多线程与并发】线程
一、概念1. 并发 ≠ 并行并发 (concurrency) 和 并行 ( parallelism) 是不同的。在单个 CPU 核上,线程通过时间片或者让出控制权来实现任务切换,达到 “同时” 运行多个任务的目的,这就是所谓的并发。但实际上任何时刻都只有一个任务被执行,其他任务通过某种算法来排队。多核 CPU 可以让同一进程内的 “多个线程” 做到真正意义上的同时运行,这才是并行。2. 程序、进程、线程、协程程序:是一个静态的概念,但可以被动态地执行。例如静静地躺在你硬盘中的QQ.exe进程:原创 2020-05-23 08:05:02 · 272 阅读 · 0 评论