
java
文章平均质量分 79
java基础及源码
秃了也弱了。
即使没有万全准备,也要勇敢迈出第一步。无论远方的风雨有多大、路有多难走。风里雨里陪伴你们,赠人玫瑰,手有余香。在技术领域,我会一如既往的坚持下去。
展开
-
Java使用MethodHandle来替代反射,提高性能
Java从最初发布时就支持反射,通过反射可以在运行时获取类型信息,但其有个缺点就是执行速度较慢。于是从Java 7开始提供了另一套API。其与反射的作用类似,可以在运行时访问类型信息,但是其执行效率比反射更高(性能几乎接近方法调用):是的一个实例,它是对Java中某个方法(包括实例方法、静态方法、构造函数等)的直接可执行引用。与传统的Java反射相比,MethodHandle更加轻量级和高效,因为它绕过了许多反射的额外开销,如访问控制检查等。原创 2025-03-24 16:18:05 · 628 阅读 · 0 评论 -
Java虚拟线程:揭开java虚拟线程的面纱
在高并发编程领域,线程一直是一个关键的概念。传统的 Java 线程是对操作系统线程的一对一映射,这种实现方式虽然简单直观,但在面对现代高并发场景时却显得力不从心。每个线程都需要占用大量系统资源,且线程切换的开销较大,这严重限制了应用程序的扩展性。为了解决这个问题,一些编程语言采用了更轻量级的并发原语-协程。比如Go语言的goroutinePython的asyncio,它们都能以极低的资源消耗支持大规模并发。而在 Java 世界中,随着JDK 21的发布,虚拟线程(Virtual Thread)原创 2025-02-11 17:25:51 · 985 阅读 · 0 评论 -
Java多线程知识点总结大全
Java并发编程实战》:永远只在更新对象的成员变量时加锁(读不加锁)永远只在访问可变的成员变量时加锁(减少锁的粒度)永远不在调用其他对象的方法时加锁(IO、耗时操作,也相当于减少锁的粒度、预防死锁)原创 2025-01-24 14:14:33 · 983 阅读 · 0 评论 -
Java开发中那些可以提升性能/效率的小技巧(持续更新)
所以,在并发情况下,会有锁竞争的场景,比如说Spring中的依赖注入,为了检查Inject类是否存在,在构造方法中做了检查。但是,这是100万次反射获取方法,280毫秒其实对于一般系统来说也影响不大了,如果是追求极致的并发,或许可以考虑一下为反射添加缓存。日常开发中,经常会用到反射,尤其是SpringAOP或者其他场景,但是经常会忽略其性能,反射的性能确实比普通的方法性能差很多。日常开发中,以及某些Spring的代码中,对于字段或者方法设置Access时,public类型的就不进行。原创 2024-09-23 21:30:00 · 1055 阅读 · 0 评论 -
Java核心 - 泛型详解
是在定义类、接口和方法时,可以在声明时通过一定的格式指定其参数类型。使用时再指定具体的类型,从而使得类、接口和方法可以被多种类型的数据所实例化或调用。这种可以在编译时进行参数类型检查的技术被称为泛型,是JDK5中引入的一个新特性。本质是参数化类型给类型指定一个参数,在使用时再指定此参数具体的值,那这个类型就可以在使用时决定。优点:把运行时的错误,提前到编译时,这样就可以在编译时把错误提示出来,避免了运行时出现错误;使用泛型可以提高代码的复用性,因为它可以支持多种类型的数据。原创 2024-07-03 09:03:35 · 1082 阅读 · 0 评论 -
AQS是什么?AbstractQueuedSynchronizer之AQS原理及源码深度分析
AQS 的全称为(AbstractQueuedSynchronizer),这个类在 java.util.concurrent.locks 包下面。其中,AbstractOwnableSynchronizer是AbstractQueuedLongSynchronizer和AbstractQueuedSynchronizer的父类。原创 2023-10-23 11:22:23 · 1079 阅读 · 1 评论 -
LongAdder为什么在高并发下保持良好性能?LongAdder源码详细分析
阿里巴巴Java开发手册中》:【参考】 volatile 解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。说明: 如果是 count++操作,使用如下类实现: AtomicInteger count = new AtomicInteger();如果是 JDK8,推荐使用LongAdder对象,比 AtomicLong 性能更好(减少乐观锁的重试次数)。在低并发下,LongAdder和AtomicLong具有相似的特征。原创 2023-10-23 11:21:08 · 1331 阅读 · 0 评论 -
Java-Atomic原子操作类详解及源码分析,Java原子操作类进阶,LongAdder源码分析
Java从JDK1.5开始提供了java.util.concurrent.atomic包,这个包中的原子操作类提供了一种用法简单,性能高效,线程安全地更新一个变量的方式。基本类型原子类包括AtomicBoolean、AtomicInteger、AtomicLong,// 自动更新当前值与给定的功能应用到当前和给定值的结果,返回更新后的值。// 自动添加给定值并获取当前值。// 自动设置的值来指定更新值,如果给定==期望值。// 递减。原创 2023-10-11 17:40:26 · 1094 阅读 · 0 评论 -
LockSupport是做什么的?深入理解Java的三种线程等待通知机制
在java.util.concurrent.locks包下,有一个不经常被人关注的类:LockSupport。用于创建锁和其他同步类的基本线程阻塞元语。总共有如下几个方法:LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,每个线程都有一个许可(Permit),但是与Semaphore不同的是,许可的累加上限是1。大概的意思就是:LockSupport中的park()和unpark()的作用分别是阻塞线程和解除阻塞线程。原创 2023-10-09 08:47:30 · 848 阅读 · 0 评论 -
一文搞懂Java线程中断协商机制,如何优雅中断一个正在运行的线程?
一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止,自己来决定自己的命运。所以,Thread.stop()、Thread.suspend、Thread.resume()等关于强制线程停止的方法都已经废弃了。在Java中,没有办法立即停止一个线程,然而停止线程本身这个功能是很重要的,比如说取消一个耗时的操作。中断,也即中断标识协商机制。Java的中断只是一种协商机制,Java并没有给中断增加任何语法,中断的过程完全需要程序员自己来实现。原创 2023-10-06 12:59:42 · 1198 阅读 · 0 评论 -
Java重构实战:动手实现一个配置加载器,并使用设计模式进行优化
自研项目中,很多时候并没有考虑使用Spring或者Springboot框架,以至于Spring那些简化配置的神器无法使用,此时就需要自己手写一个配置加载器。原创 2023-09-26 13:33:20 · 342 阅读 · 0 评论 -
JDK8:Optional详解与源码分析,如何优雅的处理空指针
在日常开发中,NullPointerException相信所有人都见过,不管你是刚入行的萌新还是骨灰级玩家,对于它都是耳熟能详的。它的出现可以说无处不在,总是能在各种场景下出现。那么对于如何防止它的出现,我们平时都是被动的采用各种非空校验,但是它还是经常能出现在我们的视线中。if(student!原创 2023-08-03 08:46:01 · 648 阅读 · 0 评论 -
JDK8:Stream流0基础使用与深入理解,Stream流源码分析
流操作是Java8提供一个重要新特性,它允许开发人员以声明性方式处理集合,其核心类库主要改进了对集合类的API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中,能让代码更加简洁,极大地简化了集合的处理操作,提高了开发的效率和生产力。同时stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。在Stream中的操作每一次都会产生新的流,内部不会像普通集合操作一样立刻获取值,而是。原创 2023-08-03 08:45:29 · 2124 阅读 · 0 评论 -
JDK8:Lambda表达式使用介绍,Lambda表达式源码及原理分析
Lambda表达式是Java8中非常重要的一个新特性,其基于函数式编程的思想,支持将代码作为方法参数进行使用。可以把Lambda表达式理解为通过一种更加简洁的方式表示可传递的匿名函数。它本身没有名称,而且不像方法那样属于某一个类,但是可以有参数列表、代码体、返回值。使用了Lambda表达式之后就不需要再去编写匿名类了。原创 2023-08-02 10:00:03 · 770 阅读 · 0 评论 -
StampedLock使用及源码分析:号称比读写锁还要快的锁
StampedLock类是在JDK8引入的一把新锁,其是对原有ReentrantReadWriteLock读写锁的增强,增加了一个乐观读模式,内部提供了相关API不仅优化了读锁、写锁的访问,也可以让读锁与写锁间可以互相转换,从而更细粒度的控制并发。也叫邮戳锁、票据锁。使用类似于ReentrantReadWriteLock,是一把独占锁,当一个线程获取该锁后,其他请求线程会阻塞等待。原创 2023-08-01 15:32:11 · 852 阅读 · 0 评论 -
JMM内存模型深入详解,探索volatile、synchronized与VarHandle深层次的奥秘
多线程下,共享变量的读写顺序是头等大事,内存模型就是多线程下对共享变量的一组读写规则。也就是说,JMM主要关注共享变量是否在线程间同步代码可能得执行顺序。也就是我们常说的,可见性与指令重排序的问题。需要关注的操作就有两种:Load、Store:Load就是从缓存读取到寄存器中,如果一级缓存中没有,就会层层读取二级、三级缓存,最后才是Memory。原创 2023-07-26 17:38:04 · 1370 阅读 · 0 评论 -
VarHandle:Java9中保证变量读写可见性、有序性、原子性利器
JMM内存模型深入详解,探索volatile、synchronized与VarHandle深层次的奥秘。原创 2023-07-25 17:35:28 · 730 阅读 · 0 评论 -
ThreadLocal源码深度详解
我们文章刚开始写的,定义ThreadLocal时定义一个匿名内部类,重写initialValue,这相当于是一个懒加载的过程,调用get方法时,如果没有设置过值,就会触发初始化过程;线程池中的核心线程都是复用的,通过下面的实例,上一个任务的ThreadLocal如果没有remove,下一个任务会拿到上一个任务的数据,抛开内存泄漏不说,这是一个非常危险的操作!我们使用下面的demo解释一下,使用0x61c88647这个黄金分割的数字,生成的下一个值,均衡的生成一个散列,并不会重复。原创 2023-06-15 18:10:20 · 829 阅读 · 0 评论 -
Java实现简单RPC框架,Springboot + javaSocket实现简易的RPC框架
RPC框架通常有基于http方式的(OpenFeign),还有tcp方式的(dubbo),我们今天就尝试使用Java的Socket自己封装一个RPC框架。客户端与服务器端之间的信息传输,就是使用该类进行传输// 类名 private String methodName;// 方法名 private Object [ ] args;// 方法参数 private Class [ ] types;// 返回值类型 // ...get set }原创 2023-06-01 11:24:15 · 1880 阅读 · 0 评论 -
Java领域的序列化与反序列化,Java的对象如何传输,常用序列化技术
我们发现对 User 这个类增加一个 Serializable,就可以解决 Java 对象的网络传输问题。Java 平台允许我们在内存中创建可复用的 Java 对象,但一般情况下,只有当 JVM 处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比 JVM 的生命周期更长。但在现实应用中,就可能要求在 JVM 停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java 对象序列化就能够帮助我们实现该功能。简单来说。原创 2023-05-31 08:41:10 · 1380 阅读 · 0 评论 -
Java正则表达式及Pattern与Matcher使用详解
符号符号示例解释匹配输入转义符\*符号“*”[ ]可接收的字符列表[efgh]e、f、g、h中的任意1个字符e、f、g、h[^]不接收的字符列表[^abc]除a、b、c之外的任意1个字符,包括数字和特殊符号m、q、5、*匹配“|”之前或之后的表达式ab|cdab或者cdab、cd( )将子表达式分组(abc)将字符串abc作为一组abc连字符A-Z任意单个大写字母大写字母。原创 2023-03-24 18:01:19 · 2786 阅读 · 0 评论 -
深入理解JDK动态代理原理,使用javassist动手写一个动态代理框架
vm options参数设置-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true,就可以把生成的代理类的源码保存在com.sun.proxy目录下面,或者用arthas来查看运行中的类信息。原创 2023-03-05 15:57:22 · 807 阅读 · 0 评论 -
CompletableFuture 异步编排使用详解
在 Java 8 中, 新增加了一个包含 50 个方法左右的类: CompletableFuture,提供了非常强大的Future 的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合 CompletableFuture 的方法。CompletableFuture 类实现了 Future 接口,所以你还是可以像以前一样通过get方法阻塞或者轮询的方式获得结果,但是这种方式不推荐使用。原创 2023-02-15 16:22:39 · 861 阅读 · 0 评论 -
Java新特性-文本块的使用与最佳实践
文字块(text blocks)这个特性,首先在 JDK 13 中以预览版的形式发布。在 JDK 14 中,改进的文字块再次以预览版的形式发布。最后,文字块在 JDK 15 正式发布。使用String的加号来拼接HTML, SQL, XML, JSON,似乎是对长文本唯一的处理方式,令人繁琐的引号和加号,可读性差不说,写起来也很麻烦。1.仅当文本块可以提高代码的清晰度时才使用文本块,特别是对于多行字符串。2.如果字符串适合用例,则始终首选使用字符串。它们更有利于应用程序性能。原创 2023-02-14 15:36:46 · 2622 阅读 · 0 评论 -
java8日期和时间API全解——更完善的日期和时间API
在 Java 8 之前,我们处理日期时间需求时,使用 Date、Calender 和 SimpleDateFormat,来声明时间戳、使用日历处理日期和格式化解析日期时间。但是,这些类的 API 的缺点比较明显,比如可读性差、易用性差、使用起来冗余繁琐,SimpleDateFormat还有线程安全问题。比如:年份的起始选择是1900年,月份的起始从0开始。// 它的打印输出效果为: Tue Mar 18 00 : 00 : 00 CET 2014。原创 2022-08-24 22:45:00 · 2102 阅读 · 0 评论 -
深入聊聊java中判等问题:你真的会用==和equals吗
判等问题是日常开发中遇到的最常见的问题之一,虽然简单但是其中蕴含着很多坑与技巧。今天咱们就一起聊聊,判等问题。对于自定义类型,如果不重写 equals 的话,默认就是使用 Object 基类的按引用的比较方式(Object 超类中的 equals 默认使用 == 判等,比较的是对象的引用)。考虑到性能,可以先进行指针判等,如果对象是同一个那么直接返回 true;需要对另一方进行判空,空对象和自身进行比较,结果一定是 fasle;需要判断两个对象的类型,如果类型都不同,那么直接返回 false;...原创 2022-08-18 23:00:00 · 669 阅读 · 0 评论 -
揭开volatile的神秘面纱——熟悉volatile 的内存语义
当声明共享变量为 volatile 后,对这个变量的读/写将会很特别。为了揭开 volatile 的神秘面纱,本文将介绍 volatile 的内存语义及 volatile 内存语义的实现。原创 2022-08-15 23:30:00 · 319 阅读 · 0 评论 -
wait/notify——熟悉java线程间通信机制之等待/通知机制
一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者,这种模式隔离了“做什么”(what)和“怎么做”(How),在功能层面上实现了解耦,体系结构上具备了良好的伸缩性,在 Java 语言中如何实现类似的功能呢?答案:Java 通过内置的等待/通知机制能够很好地解决线程间通信的功能。...原创 2022-08-15 22:15:00 · 501 阅读 · 0 评论 -
synchronized对象锁?如何用synchronized锁字符串对象,这里面的坑要注意
我们使用synchronized通常都有这样一个误区:synchronized锁住的代码块一定是所有线程都互斥的。其实不然!首先我们明确一点,synchronized锁住的是一个对象!如果锁住的这个对象,在多个线程中相同,那么这些线程访问synchronized修饰的代码块时,总是互斥的。但是!如果锁住的这个对象,在多个线程中是不同的,那么这些线程访问synchronized修饰的代码块,是不会互斥的!...原创 2022-08-15 11:01:16 · 2100 阅读 · 2 评论 -
happens-before规则——理解happens-before规则
happens-before 是 JMM 最核心的概念。对应 Java 程序员来说,理解 happens-before是理解 JMM 的关键。从 JDK 5 开始,Java 使用新的 JSR-133 内存模型(除非特别说明,本文针对的都是JSR-133 内存模型)。JSR-133 使用 happens-before 的概念来阐述操作之间的内存可见性。在 JMM 中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必 须要存在 happens-before 关系。...原创 2022-08-11 09:02:36 · 1634 阅读 · 0 评论 -
synchronized 的实现原理以及锁升级详解
在多线程并发编程中 synchronized 一直是元老级角色,很多人都会称呼它为重量级锁。但是,随着 Java SE 1.6 对 synchronized 进行了各种优化之后,有些情况下它就并不那么重了。Java SE 1.6 中为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁,在此了解一下锁的存储结构和升级过程。...原创 2022-08-10 21:15:00 · 812 阅读 · 0 评论 -
ThreadLocal父子线程传递问题——熟悉阿里的TransmittableThreadLocal
线程复用的同时,对本地变量的传递带来了新的影响,上文提到InheritableThreadLocal实现父子线程变量传递是在子线程初始化过程中,而池化的线程是不会重新初始化的,所以InheritableThreadLocal不能在线程池开辟的子线程。可以看到,开启的子线程是无法获得父线程的本地变量的,所以java引入了InheritableThreadLocal,在子线程初始化时,会将父线程的本地变量传递到子线程。在大多数实际项目中,为了节省线程开启关闭的开销,常常使用线程池来提高线程的复用。...转载 2022-07-20 13:38:26 · 1611 阅读 · 0 评论 -
依据CPU的三级缓存来解释可见性、有序性——真正的底层
我们都知道,volatile解决了变量的可见性,保证了有序性,禁止了指令重排序。那么,它是怎么做到的呢?什么是内存的可见性?CPU对指令为什么会重排序?今天全给你讲明白!(不熟悉volatile的同学们,请看这个:volatile超详细讲解)一个java进程执行的过程:打开进程(java程序) -> 将进程需要执行的main程序加载到内存中 -> 将指令加载到PC寄存器,将数据加载到Registers,ALU计算组做计算 ->计算完毕将结果写回内存。以上是单线程执行的 过程,那么多线程执行过程呢?原创 2022-06-17 18:27:34 · 931 阅读 · 1 评论 -
java监控文件的创建、修改、删除
开发过程中我们需要对某个目录或者某个文件做监听,当文件的创建、修改、删除时执行某些操作。除了使用定时任务来定时监听之外,还可以使用apache.commons.io包的监听工具类。原创 2022-06-14 22:16:53 · 736 阅读 · 0 评论 -
使用java压缩文件成zip——三种方式压缩文件速度对比
对于大文件批量压缩的问题,实际上是非常消耗时间的,怎么能提高压缩速度呢?在这里提供了三种方式压缩文件,咱们对比一下哪一个压缩速度更快。在这里提供了三个文件,压缩后的大小大概是1.1GB左右,咱们测试一下每一种压缩方式的压缩时间。结论:平均就是47秒左右。结论:平均36秒左右。注意!transferTo方法最大能读取2G的文件!结论:平均26秒左右。...原创 2022-06-09 20:31:30 · 8211 阅读 · 13 评论 -
java之Semaphore信号量做限流
Semaphore信号量非常适合高并发访问,新系统在上线之前,要对系统的访问量进行评估,当然这个值肯定不是随便拍拍脑袋就能想出来的,是经过以往的经验、数据、历年的访问量,已经推广力度进行一个合理的评估,当然评估标准不能太大也不能太小,太大的话投入的资源达不到实际效果,纯粹浪费资源,太小的话,某个时间点一个高峰值的访问量上来直接可以压垮系统。相关概念:PV(page view)网站的总访问量,页面浏览量或点击量,用户每刷新一次就会被记录一次。UV(unique Visitor)访问网站的一台电脑客户端为原创 2022-05-26 21:08:29 · 633 阅读 · 3 评论 -
ForkJoin的使用——让多个任务并行执行
文章目录写在前面直接上代码解析写在前面开发中遇到这么一个业务场景:有100个任务我需要执行,这几个任务之间并没有什么关联,只需要在这些任务都执行完毕之后,我需要一个最终的结果。此时,就需要使用ForkJoin线程池来完成多个任务并行的工作了,大大的提高了运行速度!直接上代码import java.util.ArrayList;import java.util.List;import java.util.concurrent.ForkJoinPool;import java.util.con原创 2022-05-25 21:03:59 · 890 阅读 · 2 评论 -
jdk8-stream深入详解与运行机制(旧)
目录一、基本概念二、stream的创建三、stream中间操作四、stream终止操作五、并行流详解六、收集器七、stream运行机制一、基本概念.外部迭代、内部迭代、中间操作、终止操作、惰性求值import java.util.stream.IntStream;public class StreamDemo1 { public static void main(String[] args) { int[] nums = { 1, 2..原创 2022-05-08 11:08:07 · 1153 阅读 · 0 评论 -
函数式接口-lambda函数与jdk8自带的函数接口
目录写在前面一、常见写法二、@FunctionalInterface注解三、default方法四、jdk8自带的函数接口(重点)PredicateConsumerFunctionSupplierBiFunctionjdk提供了很多基本数据类型的类,可以直接使用不需要加泛型实例写在前面本文主要是介绍jdk8自带的函数接口,默认认为读者已经了解或接触过lambda函数基础。学习jdk8自带的函数接口,主要是为了进一步学习stream流式编程。.原创 2022-05-08 10:20:09 · 611 阅读 · 0 评论 -
web项目下载文件,别在本地生成临时文件了,在此验证其效率,竟差30%的效率
目录写在前面公共文件下载方法生成临时文件方式下载测试直接输出流转输入流的方式下载测试总结写在前面有很多互联网web项目,做文件打包下载的时候,可能需要先从文件服务器下载所有文件放到临时目录,然后再将目录打包成zip临时文件,然后再返回给前端。其实这种方式是可以实现业务逻辑的,但是事实上效率真的高吗?也许可以优化!公共文件下载方法 /** * 文件下载 */ public void downloadFile(HttpServletRes..原创 2022-04-04 02:30:00 · 1121 阅读 · 0 评论