![](https://img-blog.csdnimg.cn/9cdf3064f3e34867b4e2c32358e741ef.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java系列
文章平均质量分 78
Java
兀坐晴窗独饮茶
我的个人博客 http://knightzz.cn/
展开
-
SpringBoot常用注解总结
定义在main方法入口类处,用于启动sping boot应用项目@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@Configuration@EnableAutoConfiguration@ComponentScan让spring boot根据类路径中的jar包依赖当前项目进行自动配置在src/main/resources的META-INF/spring.factories@EnableAu原创 2024-05-17 10:40:35 · 861 阅读 · 2 评论 -
SpringBoot自定义Starter
在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,比如对 web 请求的日志打印。我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,这样会非常麻烦。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个 starter,复用的时候只需要将其在 maven pom 中引用依赖即可,让 SpringBoot 为我们完成自动装配,提高开发效率。原创 2024-05-15 17:01:46 · 543 阅读 · 0 评论 -
提升代码可读性与可维护性:利用责任链模式优化你的Spring Boot代码
在现代软件开发中,构建灵活且易于维护的应用程序是至关重要的。Spring Boot作为一个流行的Java框架,提供了快速开发和简化配置的能力。与此同时,责任链模式作为一种设计模式,可以帮助我们更好地处理复杂的业务逻辑。本文将深入探讨如何将Spring Boot与责任链模式相结合,以实现可扩展且高度灵活的应用程序。我们将探讨责任链模式的核心概念,然后展示如何将其与Spring Boot的组件无缝集成。通过实际示例,你将了解如何优化代码结构,提高可读性,并在项目中实现更强大的业务逻辑处理。无论是简化工作流程、实原创 2023-08-29 20:05:09 · 497 阅读 · 0 评论 -
Elasticsearch7.x - REST 基础操作
对比关系型数据库,创建索引就等同于创建数据库在 Postman 中,向 ES 服务器发 **PUT **请求 :http://127.0.0.1:9200/shopping如果重复添加索引,会返回错误信息在 Postman 中,向 ES 服务器发 **GET **请求 ::::warning这里请求路径中的_cat 表示查看的意思,indices 表示索引,所以整体含义就是查看当前 ES服务器中的所有索引,就好像 MySQL 中的 show tables 的感觉,服务器响应结果如下:::原创 2023-05-15 20:24:20 · 579 阅读 · 1 评论 -
构造方法与方法调用指令分析 || JVM类加载与字节码技术
编译器会按从上至下的顺序,收集所有 {} 代码块和成员变量赋值的代码,形成新的构造方法,但原始构造方法内的代码总是在最后。最终方法(final),私有方法(private),构造方法都是由 invokespecial 指令来调用,属于静。编译器会按从上至下的顺序,收集所有 static 静态代码块和静态成员赋值的代码,合并为一个特殊的方法。new #2 : 是创建【对象】,给对象分配堆内存,执行成功会将【对象引用】压入操作数栈。成员方法与静态方法调用的另一个区别是,执行方法前是否需要【对象引用】原创 2022-10-19 20:55:11 · 415 阅读 · 0 评论 -
条件判断指令分析 || JVM类加载与字节码技术
参考 : https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.lcmp。以上比较指令中没有 long,flfloat,double 的比较,那么它们要比较怎么办?赋值指令是从操作数栈复制到局部变量表中 , 而累加是 直接在局部变量表中累加。其他的如 do while 和 for 其实都是类似的。原创 2022-10-19 20:54:16 · 343 阅读 · 0 评论 -
字节码指令案例分析 || JVM类加载与字节码技术
可以看到局部变量表中有三个 slot (插槽) , 0 , 1 , 2 分别对应着 args , a , b。a++ 和 ++a 的区别是先执行 iload 还是先执行 iinc。注意 : iinc 指令是直接在局部变量的slot上执行的!从字节码角度分析 a++ 相关题目。原创 2022-10-18 19:06:19 · 474 阅读 · 0 评论 -
11.盛水最多的容器 || 双指针
这个思路和计算两数之和三数之和差不多, 利用夹逼定理, 移动两个指针 , 盛水的大小时由最短的那一边决定的, 并且移动的过程中, 宽度是一直减小的。轴共同构成的容器可以容纳最多的水。找出其中的两条线,使得它们与。**说明:**你不能倾斜容器。返回容器可以储存的最大水量。原创 2022-09-27 21:16:22 · 71 阅读 · 0 评论 -
JVM垃圾回收算法与原理详解
优点 :缺点 :使用 打印GC信息执行结果如下 :可以看到,其实也是有被回收了,也就是意味着虚拟机并没有因为两个对象相互引用就不回收他们。侧面说明虚拟机并不是通过引用计数法来判断对象是否存活。虽然可引用计数法很简单,也经常被提及,但是HotSpot虚拟机却不是用这个算法来判断对象是否继续被引用,而是使用下面要介绍的算法:可达性分析算法。目前 Java 虚拟机的主流垃圾回收器采取的是可达性分析算法。这个算法的实质在于将一系列 GC Roots 作为初始的存活对象合集(live set),然后从该合集出原创 2022-09-27 08:51:57 · 553 阅读 · 0 评论 -
CyclicBarrier
循环栅栏,用来进行线程协作,等待线程满足某个计数。构造时设置『计数个数』,每个线程执行到某个需要“同步”的时刻调用 await() 方法进行等待,当等待的线程数满足『计数个数』时,继续执行功能和 countdownlatch 一样, 但是 CyclicBarrier 可以循环使用。原创 2022-09-25 14:33:20 · 93 阅读 · 0 评论 -
Semaphore
semaphore [ˈsɛməˌfɔr] 信号量,用来限制能同时访问共享资源的线程上限....................原创 2022-09-23 18:56:32 · 345 阅读 · 0 评论 -
ReentrantLock读写锁源码解析
事情还没完,在 setHeadAndPropagate 方法内还会检查下一个节点是否是 shared,如果是则调用 doReleaseShared() 将 head 的状态从 -1 改为 0 并唤醒老二,这时 t3 在 doAcquireShared 内。t3 进入 sync.releaseShared(1) 中,调用 tryReleaseShared(1) 让计数减一,这回计数为零了,进入 doReleaseShared() 将头节点从 -1 改为 0 并唤醒老二,即。的低 16 位,而读锁 使用的是。原创 2022-09-23 14:48:31 · 71 阅读 · 0 评论 -
AQS基本介绍
AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的,Semaphore,其他的诸如,,FutureTask等等皆是基于AQS的。当然,我们自己也能利用AQS非常轻松容易地构造出符合我们自己需求的同步器。AQS 全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架独占锁是不可重入锁 , 已经获得锁的话, 再次请求获得锁会导致死锁./*** 独占锁 同步器类。原创 2022-09-23 14:45:03 · 304 阅读 · 0 评论 -
StampedLock
该类自 JDK 8 加入,是为了进一步优化读性能,它的特点是在使用读锁、写锁时都必须配合戳使用StampedLock提供三种模式的读写锁,分别为写锁、悲观读锁、乐观读锁。并且是写写互斥、读写互斥、读读共享。原创 2022-09-23 14:44:08 · 302 阅读 · 0 评论 -
ReentrantLock读写锁源码解析
事情还没完,在 setHeadAndPropagate 方法内还会检查下一个节点是否是 shared,如果是则调用 doReleaseShared() 将 head 的状态从 -1 改为 0 并唤醒老二,这时 t3 在 doAcquireShared 内。t3 进入 sync.releaseShared(1) 中,调用 tryReleaseShared(1) 让计数减一,这回计数为零了,进入 doReleaseShared() 将头节点从 -1 改为 0 并唤醒老二,即。的低 16 位,而读锁 使用的是。原创 2022-09-23 14:43:31 · 222 阅读 · 0 评论 -
ReentrantLock读写锁
使用读写锁保证缓存一致性。原创 2022-09-23 14:42:52 · 346 阅读 · 0 评论 -
ReentrantLock源码解析
ReentrantLock,意思是“可重入锁”,关于可重入锁的概念在下一节讲述。ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。基本语法上,ReentrantLock与synchronized很相似,它们都具备一样的线程重入特性,只是代码写法上有点区别而已。一个表现为API层面的互斥锁(Lock),一个表现为原生语法层面的互斥锁(synchronized)。原创 2022-09-18 21:11:27 · 289 阅读 · 0 评论 -
Spring4 + SpringMVC + Hibernate4 环境搭建
Archetype 是 Maven的模板, 选择 创建好的 maven 项目是下面这样Spring 和 Hibernate 的版本 :特别注意 : Spring5 和 Hibernate5 很多地方和4是不一样的, 这里要注意的依赖版本 :xml配置 :添加相关配置整合Spring+Hibernate : 注意和 SpringMVC是和这俩没关系的, 为了防止把自己搞混, 先配置这两个applicationContext.xml这个配置部分我主要分为三个部分 :首先是第一部分 :用于扫描的注解原创 2022-09-15 19:45:47 · 774 阅读 · 0 评论 -
JVM内存结构详解
Program Counter Register 程序计数器(寄存器):作用: 是记住下一条jvm指令的执行地址特点是线程私有的不会存在内存溢出每一个线程都对应一个程序计数器, 用于存储下一个指令的地址, 不存在内存溢出的原因是 :首先,我们熟悉的栈和堆,都是可以通过运行时对内存需求的扩增导致内存不够用的情况。原创 2022-09-08 19:52:28 · 348 阅读 · 0 评论 -
Fork&&Join
Fork/Join是 JDK 1.7 加入的新的线程池实现,它体现的是一种分治思想,适用于能够进行任务拆分的 cpu 密集型运算所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直接求解。跟递归相关的一些计算,如归并排序、斐波那契数列、都可以用分治思想进行求解Fork/Join在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升了运算效率Fork/Join默认会创建与 cpu 核心数大小相同的线程池提交给 Fork/Join 线程池的任务需要继承。原创 2022-09-04 20:22:51 · 67 阅读 · 0 评论 -
任务调度线程池
的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。整个线程池表现为:线程数固定,任务数多于线程数时,会放入无界队列排队。的时候 task1 和 task2 都要开始执行, 但是由于 Timer 内只有一个线程来顺序执行队列中的任务。可以看到两个任务是同一时间执行的, 并不会因为某个任务执行时间慢影响其他的任务。所以 , 当上一个任务延时的情况下, 就会影响下一个任务的执行。原创 2022-09-03 17:51:02 · 331 阅读 · 0 评论 -
异步模式之工作线程
例如,海底捞的服务员(线程),轮流处理每位客人的点餐(任务),如果为每位客人都配一名专属的服务员,那么成本就太高了(对比另一种多线程设计模式:Thread-Per-Message)注意,不同任务类型应该使用不同的线程池,这样能够避免饥饿,并能提升效率例如,如果一个餐馆的工人既要招呼客人(任务类型A),又要到后厨做菜(任务类型B)显然效率不咋地,分成服务员(线程池A)与厨师(线程池B)更为合理。原创 2022-09-03 17:50:06 · 141 阅读 · 0 评论 -
ThreadPoolExecutor详解
当线程数达到 corePoolSize 并没有线程空闲,这时再加入任务,新加的任务会被加入workQueue 队列排队,直到有空闲的线程。如果队列选择了有界队列,那么任务超过了队列大小时,会创建 maximumPoolSize - corePoolSize 数目的线程来救急。自己创建一个单线程串行执行任务,如果任务执行失败而终止那么没有任何补救措施,而线程池还会新建一个线程,保证池的正常工作。线程池中刚开始没有线程,当一个任务提交给线程池后,线程池会创建一个新线程来执行任务。...原创 2022-08-29 18:04:10 · 542 阅读 · 0 评论 -
自定义简单连接池
实现基本的获取连接和归还连接的功能} // 省略实现的部分 }以上实现没有考虑:连接的动态增长与收缩连接保活(可用性检测)等待超时处理分布式 hash对于关系型数据库,有比较成熟的连接池实现,例如c3p0, druid等 对于更通用的对象池,可以考虑使用apachecommons pool,例如redis连接池可以参考jedis中关于连接池的实现。原创 2022-08-20 20:27:42 · 389 阅读 · 0 评论 -
共享变量之不可变对象与保护性拷贝!
主要内容 :不可变类的使用不可变类设计无状态类设计。原创 2022-08-18 18:42:51 · 156 阅读 · 0 评论 -
longAdder源码解析
LongAdder 是并发大师 @author Doug Lea (大哥李)的作品,设计的非常精巧LongAdder 类有几个关键域// 累加单元数组, 懒惰初始化 transient volatile Cell [ ] cells;// 基础值, 如果没有竞争, 则用 cas 累加这个域 transient volatile long base;// 在 cells 创建或扩容时, 置为 1, 表示加锁 transient volatile int cellsBusy;无竞争状态。...原创 2022-08-16 17:25:08 · 245 阅读 · 0 评论 -
happens-before规则与线程单例安全习题
happens-before 规定了对共享变量的写操作对其它线程的读操作可见,它是可见性与有序性的一套规则总结,抛开以下 happens-before 规则,JMM 并不能保证一个线程对共享变量的写,对于其它线程对该共享变量的读可见线程对 变量的写,对接下来其它线程对该变量的读可见线程 前对变量的写,对该线程开始后对该变量的读可见线程结束前对变量的写,对其它线程得知它结束后的读可见(比如其它线程调用 或 等待它结束)线程 t1 打断 t2()前对变量的写,对于其他线程得知原创 2022-08-06 15:20:26 · 138 阅读 · 0 评论 -
模式之固定与交替顺序执行
park和unpark方法比较灵活,他俩谁先调用,谁后调用无所谓。并且是以线程为单位进行『暂停』和恢复,不需要。原创 2022-07-25 09:42:15 · 107 阅读 · 0 评论 -
ReentrantLock 可重入锁
ReentrantLock相对于synchronized它具备如下特点可中断可以设置超时时间可以设置为公平锁支持多个条件变量与synchronized一样,都支持可重入//获取锁reentrantLock.lock();try{//临界区}finally{//释放锁reentrantLock.unlock();}中也有条件变量,就是waitSet休息室,当条件不满足时进入waitSet等待的条件变量比。...原创 2022-07-23 17:45:12 · 387 阅读 · 0 评论 -
synchronized锁原理优化
互换LockRecord的地址和MarkWord的内容ObjectRef指向锁地址轻量级锁没办法处理不同线程竞争锁的问题如果加锁失败,说明别的线程把这个锁占了就把轻量级锁升级称重量级申请一个Monitor对象让原本指向锁对象的ObjectReference重新指向重量级锁对象Monitor当前线程自己进入Monitor的EntryListBLOCKED。......原创 2022-07-14 21:40:04 · 221 阅读 · 0 评论 -
从字节码角度理解 synchronized原理
可以使用 jclasslib 插件查看字节码可可以使用原创 2022-07-08 22:18:40 · 170 阅读 · 0 评论 -
Monitor原理
Java 中的 Monitor 机制What’s a monitor in Java?浅析操作系统同步原语解析Java对象在内存空间中的构成以及对象头的概念对象头包括了关于堆对象的布局、类型、GC状态、同步状态和标识哈希码的基本信息。Java对象和vm内部对象都有一个共同的对象头格式。它是Java对象和虚拟机内部对象都有的共同格式,由两个字(计算机术语)组成。另外,如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小原创 2022-07-08 18:13:41 · 219 阅读 · 0 评论 -
卖票与转账案例
上面代码比较容易出现问题的地方在 :判断的地方容易出现超买, 因为所有线程共享同一个对象的 count线程1线程2成员变量countget count = 2调用sell(amount=1), 出售1张票count > amount, 满足条件线程上下文切换get count = 2调用sell(amount=2), 出售2张票count >= amount, 满足条件count -2 = 0put count = 0线程上下文切换count - 1 = 1put count = 1线程1线程2成员变量c原创 2022-07-08 16:36:34 · 124 阅读 · 0 评论 -
synchronized 解决共享带来的问题
两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果是 0 吗?问题分析以上的结果可能是正数、负数、零。为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作,要彻底理解,必须从字节码来进行分析例如对于 i++ 而言(i 为静态变量),实际会产生如下的 JVM 字节码指令:而对应 i-- 也是类似:而 Java 的内存模型如下,完成静态变量的自增,自减需要在主存和工作内存中进行数据交换:如果是单线程以上 8 行代码是顺序执行(不会交错)没有问题:[外链图片转存原创 2022-07-03 21:17:08 · 301 阅读 · 0 评论 -
线程运行原理
Java Virtual Machine Stacks (Java 虚拟机栈)具体示例如下 :当我们运行到主线程时, 可以看到只有主线程在活动而当我运行到 位置时 当前的活动栈帧对应着继续运行直到运行到 时可以看到此时有三个栈帧, 活动栈帧是 , 所以代码示例初始状态如下 :执行主方法, 创建 栈帧局部变量表 :继续向下执行, 执行到 方法内是 , 此时注意 :当我们继续向下执行时, 执行到 :当最后一个方法 method2 执行结束后, 会根据返回地址逐步返回, 直到结束...原创 2022-06-20 22:13:58 · 198 阅读 · 1 评论 -
多线程的应用 - 提升效率
基准测试工具选择,使用了比较靠谱的 JMH,它会执行程序预热,执行多次测试并平均cpu 核数限制,有两种思路点击 Add , 添加 groupId : , 然后添加 ArtifactId : 也可以通过maven命令创建创建完成以后记得去pom文件中将java编译版本从1.6修为1.8编写测试代码使用 maven package 打成 jar包然后命令台进入target目录下 , 执行 执行结果如上面所示 : 可以看到效率差了很多, 多线程的执行 耗费 0.022 s , 而单线程耗费 0.0原创 2022-06-19 18:54:30 · 271 阅读 · 0 评论 -
微服务系列(8)- Gateway服务网关
1. Gateway服务网关1.1 网关的作用Gateway网关是我们服务的守门神,所有微服务的统一入口, 有些微服务是企业内部使用的, 不能让所有的微服务都可以互相访问到, 所以我们需要一个特殊的 “门” 来拦截请求, 并决定是否放行Gateway的核心功能 :请求路由权限控制限流权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路原创 2022-04-24 21:35:32 · 3137 阅读 · 1 评论 -
微服务系列(7)- Feign使用与优化
1.Feign远程调用1.1 Feign介绍先来看我们以前利用RestTemplate发起远程调用的代码String url = "http://user-service/user/" + order.getUserId();User user = restTemplate.getForObject(url, User.class);RestTemplate调用存在下面的问题:代码可读性差,编程体验不统一参数复杂URL难以维护而Feign是一个声明式的http客户端,官方地址:http原创 2022-04-22 17:27:28 · 1157 阅读 · 0 评论 -
微服务系列(6)- Nacos配置管理
1.Nacos配置管理1.1 统一配置管理当微服务部署的实例逐渐增多的时候(几十上百台), 假如我们要修改配置时, 逐一修改就非常的麻烦!所以Nacos提供了统一的统一配置管理方案,可以集中管理所有实例的配置。Nacos一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。1.2 Nacos配置管理1.2.1 添加配置在配置列表中添加配置 :点击加号以后添加如下配置 : Data ID: [服务名]-[profile].[后缀]注意 :项目的核心配置原创 2022-04-22 10:59:41 · 1606 阅读 · 1 评论 -
Nacos集群搭建
Nacos集群搭建1.集群结构图官方给出的Nacos集群图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nyE7sKmx-1650596236238)(assets/image-20210409210621117.png)]其中包含3个nacos节点,然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx。我们计划的集群结构:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F68lYtlS-1650596236240原创 2022-04-22 10:57:43 · 199 阅读 · 0 评论