java
文章平均质量分 59
virtuousOne
virtuousOne
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
并发特性理解
CPU高速缓存可以分为一级缓存,二级缓存,部分高端CPU还具有三级缓存,每一级缓存中所储存的全部数据都是下一级缓存的一部分,这三种缓存的技术难度和制造成本是相对递减的,所以其容量也是相对递增的。Java线程之间的通信由Java内存模型(Java Memory Model, 简称JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。在Java中,通过synchronized关键字保证原子性,也可以通过Lock锁或者CAS进行保证。程序执行的顺序是按照代码的先后顺序。1.多线程之间如何通信?原创 2025-10-12 11:48:50 · 157 阅读 · 0 评论 -
Fork/Join框架入门
ForkJoinPool 内部有多个任务队列,当我们通过 ForkJoinPool 的 invoke() 或者 submit() 方法提交任务时,ForkJoinPool 根据一定的路由规则把任务提交到一个任务队列中,如果任务在执行过程中会创建出子任务,那么子任务会提交到工作线程对应的任务队列中。当递归深度较大时,会产生大量的子任务,这些子任务可能被调度到不同的线程中执行,而线程的创建和销毁以及任务调度的开销都会占用大量的资源,从而导致性能下降。是一个并行计算的框架,主要就是用来支持分治任务模型的。原创 2025-10-12 11:26:29 · 284 阅读 · 0 评论 -
线程池详解
是一种基于池化思想管理线程的工具。原创 2025-10-09 22:59:09 · 292 阅读 · 0 评论 -
JUC包下的并发容器
LinkedBlockingQueue采用两把锁的锁分离技术实现入队出队互不阻塞,添加元素和获取元素都有独立的锁,也就是说LinkedBlockingQueue是读写分离的,读写操作可以并行执行。原理:利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合,在新的集合上面修改,然后将新集合赋值给旧的引用。主要场景是读多写少的。是有界阻塞队列,其内部是用数组存储元素的,初始化时需要制定容量大小,利用ReentrantLocak实现线程安全。并发容器是解决多线程情况下,可以处理的集合。原创 2025-10-02 19:53:52 · 326 阅读 · 0 评论 -
JUC并发同步工具类详解
Semaphore维护了一个计数器,线程可以通过调用acquire()方法来获取Semaphore中的许可证,当计数器为0时,调用acquire()的线程将被阻塞,直到有其他线程释放许可证;线程可以通过调用release()方法来释放Semaphore中的许可证,这会使Semaphore中的计数器增加,从而允许更多的线程访问共享资源。是一种用于多线程编程的同步工具,主要用于在一个时刻允许多个线程对共享资源进行操作的场景。原创 2025-09-27 15:31:43 · 246 阅读 · 0 评论 -
CAS理解
摘要: CAS(Compare And Swap)是一种基于硬件指令的非阻塞同步机制,通过比较内存值(V)、预期值(E)和新值(N)实现原子更新。其应用广泛,如JUC中的Atomic类、AQS及ConcurrentHashMap,用于解决高并发下的线程安全问题(如i++)。Atomic类提供基本类型、引用类型及数组的原子操作,而LongAdder通过分散热点(Cell数组)优化高并发场景。 缺陷: 自旋CAS可能导致CPU开销过大; 仅支持单一共享变量原子操作; 存在ABA问题(通过AtomicStampe原创 2025-09-14 22:27:37 · 317 阅读 · 0 评论 -
ThreadLocal理解
Spring会从数据库连接池中获得一个connection,然后会把connection放进ThreadLocal中,也就和线程绑定了,事务需要体检或回滚,只要从ThreadLocal中拿到connection进行操作。每个Thrad维护一个ThreadLocalMap,这个Map的key是ThreadLocal实例本身,value才是真正要存储的值Object。ThreadLocal类用来提供线程内部的局部变量,这种变量在多线程环境下访问时能保证哥哥线程的变量相对独立于其他线程内的变量。原创 2025-09-07 14:22:14 · 322 阅读 · 0 评论 -
MapStruct详解
MapStruct是编译期动态生成getter/setter,在运行期直接调用框架编译好的class类实现实体映射。其次速度快,运行期间直接调用实现类,不会在运行期间使用发射进行转换。先简单的回忆下BeanUtils,处理Java Bean之间的属性拷贝;source:指定源对象中的字段名,该字段的值将被映射到目标对象的字段中。当然,如果Dto和实体之间的名称不一样,可以通过指向固定的字段映射即可。target:指定目标对象中的字段名,该字段将接收源对象字段的值。MapStruct的使用。原创 2025-09-06 17:16:40 · 216 阅读 · 0 评论 -
Java代码,调用ES,搜索日志分析
在实际开发中,我们可能遇到各种场景。列如,日志中打印了某些信息,但是这些信息没有入库。而我们需要回退某些功能的时候,需要依赖这些日志。那么,如何将这些日志导出成excel,然后再处理我们想要处理的。第四步:解析我们请求的结果为JSON即可,里面就是我们想要的json格式代码,然后进行导出。第三步:那么就是设置我们模拟请求的cookie。第一步:我们需要远程调用es的接口模拟请求。第六步,将解析的json通过导出写出即可完成了。第二步:封装模拟一个请求,请求我们的Es服务。第五步:引入导出依赖。原创 2025-08-09 14:09:38 · 268 阅读 · 0 评论 -
JVM对象创建内存分配
大量的对象被分配在eden区,满了后触发minor gc;垃圾回收后,剩余少量存活的被挪到survivor区,下一次eden区满了后,再次触发minor gc, 把eden区和survivor区垃圾对象回收,把剩余存活的对象一次性挪到另一块空的survivor区。运行8秒,即可占满eden区,即每8秒有100M到老年代,触发Full Gc;修改:将年轻代调大翻倍,此时运行第16秒后,移动到survivor区,下次minor gc,少量的移动到老年代;假设分配为3G的,年轻代和老年代为1G和2G;原创 2025-05-10 16:55:57 · 408 阅读 · 0 评论 -
ConcurrentHashMap源码解析(二)之------put()方法。
当sizeCtl < 0 ,大概率为-1,其他线程正在进行创建table的过程,当前线程没有竞争到初始化table的锁。p是红黑树,如果与你插入节点的key有冲突点的话,则putTreeVal()方法会返回冲突节点的引用。再次判断table为null,防止其他线程已经初始化完毕,然后当前线程再次初始化,导致数据丢失。强制设置binCount为2,因为binCount原创 2023-01-15 11:55:31 · 1107 阅读 · 1 评论 -
ConcurrentHashMap源码解析(一)之------基础属性
HashMap在单线程中非常好用,也不会出现什么问题。但是在多线程中,HashTable的效率太低。后面提供了ConcurrentHashMap解决多线程的问题,后续都以1.8的为对象进行研究。在1.8中,ConcurrentHashMap的设计与HashMap保持一致,使用了链表和红黑树的组合,当一个链表上的节点数超过8,且总个数超过64,就会触发转为红黑树。原创 2023-01-08 14:06:00 · 524 阅读 · 0 评论 -
线程池的设计与原理解析(五)之---getTask()方法
1.rs >= SHUTDOWN 成立: 当前的状态最低也是STOP状态,一定要返回 null了。4.线程池中的线程数超过 corePoolSize 时,会有一部分线程可能返回null。getTask()是工作线程在while死循环中获取任务队列中的任务对象的方法;2.前置条件 状态是 SHUTDOWN, workQueue.isEmpty()3.线程池中的线程数量,超过最大限制时,会有一部分线程返回null。1.表示当前线程获取任务是否超时;什么情况下getTask()返回null?原创 2022-12-17 14:40:47 · 1073 阅读 · 1 评论 -
线程池的设计与原理解析(四)之---runWorker()方法
2.如果task为空,则通过getTask()再去取任务,并赋值给task,如果取到的Runnable不为空,则执行该任务;在调用start()方法,调用的就是worker的run方法,实际上调用的是runWorker()方法。4.如果getTask()取到的任务依然是空,那么整个runWorker()方法执行完毕;3.执行完毕后,通过while循环继续getTask()取任务。1.如果task不为空,则开始执行task方法。1.将初始执行task赋值给task。简单的梳理runWorker的流程。原创 2022-12-17 14:09:47 · 1077 阅读 · 0 评论 -
IDEA常用插件(持续更新中......)
idea好用的插件,推荐插件,最常用的插件原创 2022-12-04 16:35:16 · 4003 阅读 · 0 评论 -
FutureTask详解
FutureTask 表示一个异步运算的任务。FutureTask 里面可以传入一个 Callable 的具体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、取消任务等操作。在学习多线程的时候,了解了FutureTask。FutureTask的构造函数。原创 2022-11-19 15:26:30 · 424 阅读 · 0 评论 -
ReentrantLock学习之---释放锁过程
当s==null表示当前节点是tail节点,>0说明当前节点的后继节点是取消状态,说明后继节点是取消状态,需要进行的操作是唤醒一个合适的节点。也可以理解为,释放锁操作在tryRelease()方法中处理,处理完成后,如果不是最后一个节点还会继续唤醒后一个节点的操作。回到release()中,当前的head节点已经被初始化,且后继节点有值,才会进行唤醒后一个节点的操作。在release()方法中,获取成功进入释放锁时,需要的操作是唤醒后继节点的操作.先看tryRelease()方法。...原创 2022-07-24 17:20:05 · 775 阅读 · 0 评论 -
ReentrantLock学习之---基础方法
针对tryAcquire,接下来看下里面的逻辑。本次主要是进入的公平锁的该方法的实现。该方法主要是将线程放入到队列中,再队列中是进行双向绑定,也及为双向链表的结构队列。这里就需要用到上篇博客中的state,获取当前线程的状态进而处理;使用双向链表新加入队列和删除锁的时候双向链表再时间和空间上更节约。另一个逻辑.即为重入锁逻辑,进行更新state的值,每次+1.用了自旋入队的方式,只有当前封装的node成功了才会跳出循环。很明显,加入队列的具体逻辑在enq()方法中。整个线程第一个入队的有一个逻辑....原创 2022-07-23 21:53:56 · 404 阅读 · 0 评论 -
ReentrantLock学习之---基本属性
通过简易的模仿公平锁后,对ReentrantLock的源码进行了学习。waitStatus主要是通过状态判断节点。先对节点Node的属性进行了解。原创 2022-07-17 11:50:58 · 169 阅读 · 0 评论 -
ReentrantLock学习之公平锁过程
ReentrantLock支持公平锁和非公平锁,默认使用非公平锁。Node封装节点,里面包含有前置节点和引用节点和线程信息。在源码中,加公平锁的时候,主要是进行该段代码逻辑获取加锁。在ReentrantLock实现类里面,有几个变量。在公平锁加锁的过程中,还有一段逻辑是获取锁的过程。模拟ReentrantLock的加锁过程。通过源码可以发现公平锁的加锁方法。自定义一个Lock进行实现。主要记录公平锁里面的实现。...原创 2022-07-16 20:05:10 · 591 阅读 · 0 评论 -
Synchronized理论
Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。偏向锁:撤销偏向锁为什么需要在安全点执行?线程获取锁的第一步就是向线程栈的锁记录空间中push一条锁记录信息。并且每次重入,都会插入一条心的锁记录,用于表示重入次数。锁记录空间原则上只允许本线程操作,所以一定是线程安全的。当偏向锁线程依然持有偏向锁时,说明偏向锁线程锁记录空间中一定存在该lock的LockRecord记录。偏向锁撤销,就需要将偏向锁升级为“轻量级锁”。轻量级锁:场景:A和B两个线程,运行过程中获取原创 2022-07-12 10:24:25 · 385 阅读 · 0 评论 -
Netty学习之---Selector
在入门学习netty的时候,我们就写过一个简单client连接service的代码;1:client代码 public static void main(String[] args) throws Exception{ SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("localhost",8080)); System.out.println("waitin原创 2022-05-29 13:15:23 · 518 阅读 · 0 评论 -
Netty之三----java NIO基础
Netty 是基于Java NIO 封装的网络通讯框架,只有充分理解了 Java NIO 才能理解好Netty的底层设计。Java NIO 由三个核心组件组件:BufferChannelSelector一.Channel是一个通道,它就像自来水管一样,网络数据通过 Channel 这根水管读取和写入。传统的 IO 是基于流进行操作的.常见的channel实现类有:1.FileChannel: 读写文本数据 public static void main(String[] args) t原创 2022-05-14 15:38:39 · 214 阅读 · 0 评论 -
Netty之二----源码环境搭建
netty源码环境搭建原创 2022-05-10 21:10:49 · 730 阅读 · 0 评论 -
学习Netty之---Hello Netty
Not faster than NIO (epoll) on unix systems (which is true)There is no daragram suppportUnnecessary threading model (too much abstraction without usage)以上就是Netty目前还是使用NIO的方式的原因;BootStrap: 是Netty框架的启动类和主入口类,分为客户端BootStrap和服务器类ServerBootStrap两种。Channel:原创 2022-05-04 17:33:37 · 765 阅读 · 0 评论 -
深入理解网络通信
今天温习了下之前的网络通信,以及TCP/IP相关的知识。计算机网络的标准定义利用通信线路将地理上分散的、具有独立功能的计算机系统和通信设备按不同的形式连接起来,以功能完善的网络软件及协议实现资源共享和信息传递的系统。OSI七层模型物理层: 网线物理层数据链路层:提供介质访问和链路管理网络层:IP及路由选址传输层:建立和管理端到端的连接会话层:建立会话表示层:数据格式转换、数据加密应用层:为应用程序提供服务TCP/IP 五层模型TCP:一种可靠的数据传输,面向连接。UDP:不可靠原创 2022-04-27 09:35:27 · 1532 阅读 · 0 评论 -
JVM学习之---了解JIT
先对JVM进行一个说明。jvm只识别字节码,所以jvm跟语言是解耦的,jvm运行的是class文件,像Groovy,Kotlin,Scala等语言,他们都可以转移成字节码,也都可以再jvm上运行,这就是JVM的跨语言的特征。解释执行与JIT解释执行:主要是执行字节码指令,一般这些指令会按照顺序解释执行。JIT:在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各种层次的优化。也称为及时编译。(Just In Time Compiler)在JDK10之前(列如jdk8)内置了两个原创 2022-04-12 13:06:58 · 2408 阅读 · 0 评论 -
JVM学习之十---调优实战
Arthas 是阿里巴巴的开源Java诊断工具。Api网址如下https://alibaba.github.io/arthas下载jar包https://arthas.gitee.io/arthas‐boot.jar在Linux中,通过 java -jar就可以运行。打印GC日志方法,在JVM参数里增加参数,%t 代表时间 ‐Xloggc:./gc‐%t.log ‐XX:+PrintGCDetails ‐XX:+PrintGCDateStamps ‐XX:+PrintGCTimeStamps原创 2022-04-11 19:17:44 · 620 阅读 · 0 评论 -
JVM学习之九---调优工具入门
在学习项目调优之前,先对一些基础信息进行学习。通过jps命令,查看进程id.查看堆栈信息jmap -heap 10828导入堆内存到本地jmap -dump:format=b,file=eureka.hprof 10828通过jdk自带的工具进行导入 jvisualvm一:Jstack命令jstack加进程id查找死锁jstack找出占用cpu最高的线程堆栈信息1.使用命令 top -p ,显示Java进程的内存情况。pid 是Java进程号二:Jinfo命令查看郑州原创 2022-04-10 17:11:13 · 3523 阅读 · 0 评论 -
JVM学习之八---垃圾收集器G1
G1收集器(-XX:+UseG1GC)G1(Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器。以极高的概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征。G1将Java堆划分为多个大小相等的独立区域(Region),jvm最多可以有2018个Region。一般Region大小等于堆大小/2048,比如堆大小为4096M,则Region大小为2M。G1保留了年轻代和老年代的概率,但不再是物理隔阂了,他们都是Region的集合。默认年轻代对堆内存的占原创 2022-04-09 21:50:32 · 1884 阅读 · 0 评论 -
JVM学习之七---底层三色标记算法
垃圾收集底层算法实现三色标记在并发标记的过程中,因为标记期间应用程序还继续跑,对象间的引用可能发生变化,多标和漏标的情况就有可能发生。黑色:表示对象已经被垃圾收集器访问过,且这个对象的所有引用都已经扫描过。黑色的对象代表已经扫描过,它是安全存活的,如果有其他对象引用指向了黑色对象,无须重新扫描一遍。黑色对象不可能直接指向某个白色对象。灰色:表示对象已经被垃圾收集器访问过,但这个对象只是存在一个引用还没有被扫描过。白色:表示对象尚未被垃圾收集器访问过。显然在可达性分析刚刚开始的阶段,所有的对象都是原创 2022-04-09 16:04:27 · 522 阅读 · 0 评论 -
JVM学习之六---垃圾收集器
了解垃圾收集器之前,先看下他们的算法。一:垃圾收集算法1.复制算法为了解决效率问题,“复制”收集算法。它可以将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就降还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。这样就每次的内存回收都是对内存区间的一半进行回收。2.标记-清除算法算法分为,标记和清除两个阶段:标记存活的对象,统一回收所有未标记的对象.它是最基础的收集算法,比较简单,但是会有两个明显的问题:效率问题(如果需要标记的对象太多,效率不高)空间问题(如果原创 2022-04-09 12:06:05 · 521 阅读 · 0 评论 -
JVM学习之五----字节码文件
今天学习了字节码相关的知识,进行记录一下。一:解读Class文件public class Student { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}上边的java文件编译后会生成对应的class文件:Student .class原创 2022-04-05 21:34:59 · 635 阅读 · 0 评论 -
JVM学习之四-----对象内存分配与回收
对象内存分配的流程图如下:对象栈上分配我们通过jvm内存分配可以知道Java中的对象都是在堆上进行分配,当对象没有被引用的时候,需要依靠GC进行回收内存,如果对象数量较多的时候,会给GC带来较大的压力,也间接影响了性能。为了减少临时对象在堆内分配的数量,jvm通过逃逸分析确定该对象不会被外部访问。如果不会逃逸可以将该对象在栈上分配内存,这样对象所占用的内存空间可以随栈而销毁,减轻了垃圾回收的压力。对象逃逸:就是分析对象动态作用域,当一个对象在方法中被定义后,它可能被外部方法所引用,列如作为调用参数传原创 2022-04-04 16:53:37 · 366 阅读 · 0 评论 -
JVM学习之三----对象创建
在创建Java对象的过程中,通过代码是new,在内部的执行流程如下一.类加载检查:虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表类是否已被加载、解析和初始化过。如果没有,那么就必须执行相应的类加载过程。二.分配内存:对象所需内存的大小在类加载完成后便可以确定,为对象分配空间的任务等同把一块确定大小的内存从Java堆中划分出来。这个步骤有两个问题,如下:1.如何划分内存。2.在并发情况下, 可能出现正在给对象A分配内存,指原创 2022-04-04 11:55:38 · 1269 阅读 · 0 评论 -
JVM学习之二----整体结构深入了解
在学习JVM的时候,先了解一张整体的结构图和对应的名词。1.堆:存储类实例,一个jvm只有一个堆内存。2.栈(虚拟机栈):存储当前线程运行方法时所需要的数据,指令,返回地址等。3.程序计数器:指向当前线程正在执行的字节码的地址,行号。4.方法区(元空间):存储类信息,常量,运行时常量,静态变量等。5.本地方法栈:同虚拟机栈,不同的是,它存的本地方法的数据。写一个简单的demo程序public class Math { public int compute(){ in原创 2022-03-20 18:38:15 · 236 阅读 · 0 评论 -
JVM指令手册
JVM指令手册栈和局部变量操作将常量压入栈的指令aconst_null 将null对象引用压入栈iconst_m1 将int类型常量-1压入栈iconst_0 将int类型常量0压入栈iconst_1 将int类型常量1压入操作数栈iconst_2 将int类型常量2压入栈iconst_3 将int类型常量3压入栈iconst_4 将int类型常量4压入栈iconst_5 将int类型常量5压入栈lconst_0 将long类型常量0压入栈lconst_1 将long类型常量1压入栈原创 2022-03-20 17:33:12 · 418 阅读 · 0 评论 -
JVM学习之一-----类加载机制
当我们运行一个Java的程序的时候,首先需要通过类加载器把主类加载到JVM中。通过Java命令执行代码的大体流程:一个流程的操作如下图这里主要看类加载器,Java里有如下加载器1.引导类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar,charsets.jar等2.扩展类加载器:负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包。3.应用程序加载器,负责加载ClassPath路径下的类包,主要是自己写的那些类4.自定义加载器,原创 2022-03-14 11:48:45 · 148 阅读 · 0 评论 -
Java返回封装类
在一个项目开发的过程中,需要使用统一的返回封装对象。这样里面有统一的code, 和对应的message.既方便了后端,也方便前端。1.代码:public class FastResponse<T> implements Serializable { @ApiModelProperty(value = "code编码") private String code; @ApiModelProperty(value = "返回信息") private String原创 2022-01-07 16:58:59 · 1345 阅读 · 0 评论 -
设计模式之----Java责任链模式和建造者模式结合使用
上篇介绍了简单的责任链模式的业务场景和使用,在实际的代码中,可能需要结合多种进行使用才会更好。上篇文章的在service的实现就写的很臃肿,必须指定next,这些在业务场景中都是不能做到很优雅的处理业务。接下来就是对上一篇的责任链模式进行改造,引入建造者模式。建构者模式:建造者设计模式的核心在于隐藏内部构建细节,通过外部的Builder来实现构建。Builder负责Product类对象的具体过程构建,Director负责指导Build,要求Builder按照其指定的顺序去完成Produt的构造。最后原创 2021-11-28 16:13:35 · 1727 阅读 · 1 评论
分享