
Java高级
文章平均质量分 66
石头wang
平凡码农,强迫症,抠细节。
展开
-
Collections.sort 的多线程安全问题
在实际的工作中,遇到了多线程操作 Collections.sort 导致了 ConcurrentModificationException。多线程操作了同一个共享变量导致。有时候不报错(较少时候,试了很多次才出现如下)代码改进,可以将list对象作为锁对象。原创 2023-04-07 08:30:00 · 937 阅读 · 1 评论 -
lambda表达式之 “Foo:new“ 这种写法
lambda表达式之 "Foo:new" 这种写法原创 2023-02-12 20:55:06 · 267 阅读 · 0 评论 -
List如何一边遍历,一边删除?
本文探讨对一个List遍历,并且遍历过程有删除操作,什么才是正确的做法直接上代码原创 2022-11-04 09:00:00 · 1440 阅读 · 0 评论 -
怎么看出 Java 的 Comparator是升序还是降序
怎么看出 Java 的 Comparator是升序还是降序原创 2022-10-30 08:45:00 · 3012 阅读 · 2 评论 -
怎么中断正在debug的请求(放弃此次http请求)
有时候我们用IDEA进行debug,跑进来了,debug到某个断点或某一行,如果此时我们不想继续走下去(中断此次http请求,或者说中断此次debug),要怎么做?原创 2022-10-20 20:27:50 · 5464 阅读 · 1 评论 -
防止电脑睡眠的Java程序
防止电脑睡眠的Java程序原创 2022-10-17 09:14:04 · 906 阅读 · 1 评论 -
Java 中如何比较两个BigDecimal 以及BigDecimal的坑
精度就是小数点后的位数(官方文档解释得很复杂…)// 1。原创 2022-09-04 16:45:22 · 4568 阅读 · 0 评论 -
Git flow流程介绍之我的理解(结合实际)
本文讲述git flow的使用,除了git flow,还有github flow和gitlab flow,感兴趣的话可以自己查资料。有两个分支是长期分支,所谓长期分支,不是用完就删、是长期存在的分支辅助分支,或者叫临时分支,用完在特定某个时间会删掉除此以外,可能会有一些别的常见的分支,这些分支和git flow用到的分支无关,因为常见所以列一下补充说明:develop分支,按正常的流程的话,应该是和master一致的代码状态,即处于相同的commit id或revision(理想状态)(commit id在原创 2022-07-11 21:15:00 · 520 阅读 · 0 评论 -
try-catch之后就万事大吉不会抛出异常给调用者了吗
背景作为Java程序员,spring一定很熟悉了,对于@Transactional 那肯定是再熟悉不过了。下面会展示一个大坑,可能90%的人都不知道这里可能会出问题,见伪代码@Configuration@EnableSchedulingpublic class A { @Autowired private B b; // 每天夜里2点 @Scheduled(cron = "0 0 2 * * ?") public void task() { b.doJob(); }}@S原创 2022-03-07 16:13:45 · 1573 阅读 · 0 评论 -
怎么计算Java对象占用多少内存,对象的内存结构(简单易懂)
怎么计算Java对象占用多少内存,对象的内存结构背景Object obj = new Object() 这个对象在堆中占用多少字节?要知道答案,先要知道Java对象的结构,即是由什么部分组成的?注意本文谈的都是64位虚拟机。Java对象在内存中的组成一个Java对象,在堆中究竟占多大内存?怎么计算? 首先它是由4部分组成的mark wordklass pointer(类指针,指向Xxx.class 的)Instance datapaddingMark word 固定的8字节;Kla原创 2022-03-02 22:24:01 · 1714 阅读 · 0 评论 -
线程的状态转换以及用代码证明(看此一篇即可,带图,带代码验证)
背景带你了解Java中的线程状态,有图,有代码展示,全是干货。概述你看Thread类里的State枚举,就是Java线程的状态了。网上的状态非常多,你看这个枚举比较权威,各种名词,什么可运行状态,就绪状态,乱七八糟的,记英文即可。new:刚 new 出来的线程还未 start() 就是 new 状态terminated:线程将代码运行完毕了就是 terminated 状态timed_waiting:timed是 “带有时间的” 的意思。带有时间的等待,比如常用的sleep(millis)w原创 2022-03-01 12:30:00 · 337 阅读 · 0 评论 -
关于同步、异步、阻塞和非阻塞、多路复用(IO系列一)
关于同步、异步、阻塞和非阻塞、多路复用一、背景网站的资料非常多,各种说法都有,我这个资料是总结于比较权威的机构的视频,并非从网上其他地方粘贴过来的,有自己的思考和理解。我也是这么学习和摸索过来的。二、理解同步、异步这几个词,一般都会在学习IO,尤其是网络IO的时候碰到,组合的话有4种(其中有一种实际上是不存在的):同步阻塞、同步非阻塞、异步阻塞、异步非阻塞首先,先理解什么是阻塞和非阻塞。阻塞就是某个线程在调用某个方法的时候干不了别的活,阻塞住了。比如,线程 t 调用方法 f ,只有当 f原创 2022-02-23 21:38:36 · 244 阅读 · 0 评论 -
shell或bat脚本是不是顺序执行,是多线程吗,会不等待java执行结果吗
背景研究bat/sh脚本是否是多线程执行的(或者说对java的jar进行调用是否调用后就立即返回,还是需要等到执行完毕再执行下面的脚本)动手实验Test.java类,代码如下public class Test { public static void main(String[] args) throws InterruptedException { System.out.println("------- main enter ------------"); i原创 2021-10-23 10:55:27 · 830 阅读 · 0 评论 -
Java中打印日志的坑(不打印堆栈信息)
背景打印日志的大坑。很多同事不打印堆栈信息直接这么写log.error("exception occur! param1:{},param2:{}", param1, param2);或log.error("exception occur! param1:{}", e.getMessage());或log.error("exception occur! param1:{}", e.toString());这真的是个大坑,没有堆栈信息有时候很难排查问题。首先 getMessage()原创 2021-09-28 09:37:32 · 10525 阅读 · 2 评论 -
细数编程习惯七宗罪(持续更新)
细数编程习惯七宗罪SQL 写在 java 文件里写错不容易发现,维护成本高。强烈建议写在 xml 里,配合 idea 插件 mybatis ,不但有智能提示,而且写错也会提醒,另外 mapper.java 接口和 xml 实现互相跳转。英文不过关,有些英语单词看着就不专业比较专业的,比如:management (mgmt 或 mgnt)、manager (mgr)权限:这个我用得比较杂,用auth、priv(privillege)、permission负责人用:charge原创 2021-09-10 12:44:28 · 145 阅读 · 0 评论 -
关于Long转String和js丢失精度截断的问题
背景Java后端的 Long(long) 类型字段,在web接口返回这种类型的值给前端时,会发生截断(即js会精度丢失,因为后端的Long的最大值超过了前端js能表示的值)哪些情况下发生截断如果前端不是用 js框架则不会截断,比如用postman调用就不会截断,浏览器地址栏直接请求也不会截断前端用 js 类型的框架可能会发生截断,但是只有在实际值超过js的最大范围的时候才会截断截断的一般特征是 000 结尾,比如 9223372036854776000如果 Long longValue 实际值原创 2021-08-11 15:52:25 · 3002 阅读 · 0 评论 -
长久以来,你不懂的字符编码和字符集,这里都有
(从OneNote复制过来格式有点变了,大体不影响阅读)常见的字符集或编码:ASCII占一个字节。最高位固定是0,共有2^7=128种表示方法,事实上128种编码都被利用起来了,没有浪费,详细查看ASCII编码表GB2312兼容ASCII,占用1-2个字节。除了所兼容的ASCII是1字节外,其余的都是2字节。收录了6763个汉字以及682个特殊符号。GBK(也叫cp936)兼容GB2312,兼容ASCII,也是占用1-2字节(除了所兼容的ASCII是1字节外,其余的都是2字节)原创 2021-07-11 22:01:18 · 5719 阅读 · 1 评论 -
关于SQL注入(有例子)以及我的一些想法
背景本文详细讨论sql注入的那些事情。聊聊自己的看法。并且会提供sql注入的例子。sql注入的例子例子就不用jdbc的 API 来演示了。我直接用了springboot+mybatis来模拟出来1、代码写一个controller的接口@GetMapping("/user/list") public Object listUser( @RequestParam String name ) { return userService.list原创 2021-07-02 18:04:37 · 203 阅读 · 0 评论 -
漫聊 ThreadLocal (内存泄漏,弱引用)
漫聊 ThreadLocal (内存泄漏,弱引用)背景本文漫聊 ThreadLocal,想到什么写什么。大概会谈到几个问题关于ThreadLocal 和线程同步ThreadLocal 在 JDK 中的实现ThreadLocal 的内存泄漏风险,以及关于它弱引用,讨论 “弱引用是引起内存溢出的原因吗?”如何避免内存泄漏的风险1、关于ThreadLocal 和 线程同步解决线程访问共享变量的问题,可以使用线程同步技术,无论是synchronized还是 JUC的lock。使用synchro原创 2021-05-11 15:54:48 · 524 阅读 · 0 评论 -
如何安全地使用 Lock 的unlock() 而不会抛出异常导致程序终止
如何安全地使用 Lock 的unlock() 而不会抛出异常导致程序终止背景我们使用 synchronized 的话,不需要我们手工操作lock() 和 unlock(),但是在使用 juc Lock 的时候就需要注意,不注意这些细节,将为你的程序埋下坑,卖容易发现的坑还好,偏偏有些坑是比较隐蔽的。正确的 unlock()如何正确的使用Lock#unlock(),如下建议别用 Lock lock = new ReentrantLock()这样的代码,直接用实现类 ReentrantLock l原创 2021-04-11 22:39:19 · 3504 阅读 · 0 评论 -
如何判断是否当前线程持有锁
如何判断是否当前线程持有锁背景有时候我们必须知道是否当前线程持有锁,怎么知道如果用synchronized,用Thread.holdsLock(lockObj) 获取如果使用 Lock(juc下的),则用 lock.isHeldByCurrentThread() (不能用 Thread.holdsLock(lockObj))注意 Lock 接口本身是没有 isHeldByCurrentThread 接口的,必须使用ReentrantLock、ReentrantWriteLock这些实现类。原创 2021-04-11 21:07:54 · 3661 阅读 · 0 评论 -
使用Redisson作为分布式锁
概述1Redisson 是 redis 的一个Java客户端,但是最为人熟知的是它的分布式锁的功能。所以分布式锁就不要自己实现一套了,人家帮你实现了并且考虑得比你周全得多代码健壮得多。2Redisson 除了所熟知的分布式锁的功能,其实也跟其他的Redis的Java客户端一样,有操作redis的功能,例如// string类型的,key是abc,值是vvvRBucket<String> s = redissonClient.getBucket("abc");s.set(原创 2021-03-12 16:26:37 · 822 阅读 · 0 评论 -
关于java读取环境变量、虚拟机参数
关于java读取环境变量、虚拟机参数本文系统研究在springboot启动时传入参数,对于非springboot的普通 java项目也是相同的。传参的参数类型程序参数(Program arguments)虚拟机选项(VM options)环境变量(Environment variables)后续为了方便,有时会称呼为:程序参数,vm参数,环境变量如何传参,如图:1、在IDEA等工具中是如何传的?如图:注意:环境变量的命名建议不要用 my.env.var (带点的格式),虽然在i原创 2020-09-09 17:47:37 · 5326 阅读 · 0 评论 -
Java运行参数分类
Java运行参数设置1.概述Java支持的运行参数包括如下几种:标准参数(-):所有的JVM实现都必须实现这些参数的功能,而且向后兼容;非标准参数(-X):默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;非Stable参数(-XX):此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用;2. 标准参数标准参数又可以分为如下几种:运行模式相关的,如-server,-client类,jar路径相关的,如-cp,-classpath转载 2020-08-17 13:42:06 · 586 阅读 · 0 评论 -
slf4j日志添加全局唯一的请求ID(requestId,MDC)
背景我们希望springboot默认的日志框架slf4j,在打印日志时,每行数据都有一个请求ID,这样就很方面追踪日志。并且可以在linux中用将所有该请求ID的日志写在单独的文件里(grep 你的RequestId xxx.log > 该请求ID的所有日志.log)办法slf4j有个MDC的类,是ThreadLocal的实现,保存在这里的变量会绑定到某个请求线程,于是在该请求的线程里...原创 2019-12-11 17:31:59 · 11348 阅读 · 3 评论 -
如何防止表单数据重复提交
背景有时候我们希望避免表单重复提交,比如网络慢,点击页面提交按钮后无反应,用户重复多次点击导致多次提交请求给后端接口。如何防重复提交前端措施前端可以在点击按钮后进入一段时间的loading,让按钮在loading期间不可再次点击。loading的时长可以直到后端接口返回,也可以自己定义一个较短的时间,比如2秒。后端措施情况一这种情况适用于提交的表单数据有一个比较唯一的标识,比如 “...原创 2019-12-11 16:57:42 · 453 阅读 · 0 评论 -
关于环境变量的理解,maven有没有必要配置MAVEN_HOME或M2_HOME,tomcat一定要设置JAVA_HOME环境变量吗
前言本文讨论关于环境变量的理解,maven有没有必要配置MAVEN_HOME或M2_HOME,tomcat一定要设置JAVA_HOME环境变量吗关于环境变量我们知道配置环境变量后,访问命令可以省略一长串的路径,直接通过 “短名” 即可。例如在Windows平台安装了JDK我们会配置一下JAVA_HOME变量,然后再把 %JAVA_HOME%\bin 配置在Path里,这样在访问 java.e...原创 2019-11-05 10:50:34 · 12097 阅读 · 1 评论 -
ClassLoader、双亲委派机制、自定义类加载器实践
ClassLoader、双亲委派机制、自定义类加载器双亲委派模型如果一个类加载器收到了要加载某个类的请求,它自己不会立即加载,而是委托给上一级的类加载器,一直委托到顶层,从顶层向下依次加载这个类,加载成功就跳出,否则一直往下,最终加载失败就会抛出ClassNotFoundException。如果加载过,则不需要再次走这个流程。注意:有些文章描述的父类加载器,我觉得表述为上级类加载器更加贴切,...原创 2019-04-26 15:14:28 · 275 阅读 · 0 评论 -
可重入锁详解(什么是可重入)
可重入锁详解概述什么是 “可重入”,可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。例如package com.test.reen;// 演示可重入锁是什么意思,可重入,就是可以重复获取相同的锁,synchronized和ReentrantLock都是可重入的// 可重入降低了编程复杂性public class WhatReentrant { public sta...原创 2019-04-26 15:17:26 · 120401 阅读 · 83 评论 -
volatile关键字和Java内存模型
volatile关键字和Java内存模型Java内存模型(Java Memory Model,JMM)CPU的内存模型CPU很快,内存很慢,为了充分利用CPU,出现了如下解决方案:出现了高速缓存这里的内存,也是主内存(main memory),就是我们说的内存条;高速缓存,就是集成在CPU里的多少级的缓存。引入高速缓存,也带来了"缓存一致性"问题。CPU不是直接读主内存的数据,它是...原创 2019-04-26 15:19:33 · 371 阅读 · 0 评论 -
Java线程状态的转换和API
Java线程状态的转换和API线程状态最权威的资料参考官方 Thread源码里的内部枚举 java.lang.Thread$State 的说明。其描述仅仅缺失了对于runnable状态更加细致的描述,runnable应该拆分成ready和running。除了官方的资料,下面也会综合若干博客的资料图。有些状态的名称可能比较混乱,有多种叫法,甚至出现含义的差异,需要读者自行理解。线程状态转换...原创 2019-04-26 15:21:33 · 881 阅读 · 0 评论 -
JUC的Lock和build-in的synchronized是如何实现的
JUC的Lock和build-in的synchronized是如何实现的补充JUC的Lock是如何实现的通过Lock对象的一个int标记位(名为state),记录此lock占用的线程数。如果为0表示此lock无占用,则不阻塞,如果>0则表示暂用,需要阻塞。阻塞使用和释放阻塞使用LockSupport的park/unpark来实现,其调用更底层的native方法来实现。Lock中大量使...原创 2019-04-26 15:23:04 · 378 阅读 · 0 评论 -
JVM 相关知识(一篇入门)
JVM 相关知识(一篇入门)JVM 的内存是如何划分的? 堆是如何划分的?1、JVM内存根据JVM规范,JVM内存划分为堆(heap)栈(虚拟机栈,VM Stack)本地方法栈(native method stack)方法区(method area)程序计数器(program counter register)补充:常量池是方法区的一部分;在堆中划出一块,称之为非堆或永...原创 2019-04-26 15:24:52 · 378 阅读 · 0 评论 -
Lock的API说明
Lock的API说明概述其实觉得"锁",获取"锁"的说法似乎不太符合中国人的思维,这个"锁"其实就是一个"令牌",有令牌就能进入,无令牌就不能进入。这么说来这个"锁"其实应该叫"钥匙"。当然这里应该还有一个概念,叫房间,这个钥匙是对应什么房间的(锁住什么东西,即锁住什么范围)。所以光叫"钥匙",似乎也不太准确。所以西方人的这个"锁",应该有两个概念“锁对象”,就是我们说的"钥匙"“锁...原创 2019-04-26 15:26:39 · 910 阅读 · 0 评论 -
一篇文章理解inner join/left join/right join的细节
一篇文章理解inner join/left join/right join的细节本文强烈建议自己动手实验。两表连接比较简单,可以直接跳到多表连接查看结论无论是双表还是多表关联,可以 通过分解步骤来化解复杂性。比如三张表,先考虑前两张表进行关联,得到的结果想象成临时表,再跟第三张表关联。连接的顺序对结果是会产生影响的!一、两表1、一对一people(id,name);id_card(...原创 2019-09-10 14:48:09 · 710 阅读 · 0 评论 -
关于PageHelper的坑,导致莫名其妙的sql错误的问题
关于PageHelper的坑,导致莫名其妙的sql错误的问题前言PageHelper 用得好,能省很多功夫。用得不好会埋下很大的隐患,并且很难发现。本文就是讨论这个很难发现的坑。症状出现莫名其妙的分页混乱原来不分页的sql却只查出了部分数据,观察sql发现sql被添加了limit或者sql语句报错观察该sql语句有limit,但limit后面又被添加了limit上述症状比...原创 2019-09-10 19:56:02 · 7203 阅读 · 0 评论 -
详解Java线程池参数
详解线程池参数目前线程池的类一般使用spring的:org.springframework.scheduling.concurrent.ThreadPoolTaskExecutorJDK的:java.util.concurrent.ThreadPoolExecutor它们的配置差不多,spring的做了一些配置参数的简化,最终调用JDK的API参考资料:https://blog.c...原创 2019-02-16 12:18:55 · 3529 阅读 · 1 评论