One Trick Per Day

简介: 本文总结Java开发中的6个实用技巧:合理初始化Map容量、避免Executors创建线程池导致OOM、Arrays.asList后不可修改、遍历Map优先使用entrySet、SimpleDateFormat避免static并发问题、并发更新记录时合理加锁。遵循这些规范可提升代码安全性与性能,推荐结合Guava等工具优化实现。

One Trick Per Day

1.初始化Map大小并非用多少指定多少
●初始化Map并非用多少初始化Size是多少,建议使用Guava,避免扩容引起的动荡()
说明
●如:Map<String, String> map = new HashMap<>(1); 在具体使用时,并非size=1,而是最近的2的幂等,如1实际是2,3实际是4,9实际是16
使用方法
●依赖gvaua:Map<String, String> map = Maps.newHashMapWithExpectedSize(7);
●手动声明:Map<String, String> map = new HashMap<>(实际存储个数 / 0.75 + 1);
2.线程池初始化严禁使用Executors
使用线程池时候,我们可能会使用下面四个场景,这在alibaba代码规范中都是明令禁止的
我们先来一个简单的例子,模拟一下使用 Executors 导致 OOM 的情况。
通过指定 JVM 参数:-Xmx8m -Xms8m 运行以上代码,会抛出 OOM:
以上代码指出,ExecutorsDemo.java 的第 16 行,就是代码中的 executor.execute(new SubThread());。
通过上面的例子,我们知道了 Executors 创建的线程池存在 OOM 的风险,那么到底是什么原因导致的呢?我们需要深入 Executors 的源码来分析一下。其实,在上面的报错信息中,我们是可以看出蛛丝马迹的,在以上的代码中其实已经说了,真正的导致 OOM 的其实是 LinkedBlockingQueue.offer 方法。
如果读者翻看代码的话,也可以发现,其实底层确实是通过 LinkedBlockingQueue 实现的:
如果读者对 Java 中的阻塞队列有所了解的话,看到这里或许就能够明白原因了。Java 中 的 BlockingQueue 主 要 有 两 种 实 现, 分 别 是 ArrayBlockingQueue 和 LinkedBlockingQueue。ArrayBlockingQueue 是一个用数组实现的有界阻塞队列,必须设置容量。LinkedBlockingQueue 是一个用链表实现的有界阻塞队列,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为 Integer.MAX_VALUE。这里的问题就出在:不设置的话,将是一个无边界的阻塞队列,最大长度为Integer.MAX_VALUE。也就是说,如果我们不设置 LinkedBlockingQueue 的容量的话,其默认容量将会是 Integer.MAX_VALUE。 而 newFixedThreadPool 中创建 LinkedBlockingQueue 时,并未指定容量。此时,LinkedBlockingQueue 就是一个无边界队列,对于一个无边界队列来说,是可以不断的向队列中加入任务的,这种情况下就有可能因为任务过多而导致内存溢出问题。上面提到的问题主要体现在 newFixedThreadPool 和 newSingleThreadExecutor 两个工厂方法上,并不是说newCachedThreadPool 和 newScheduledThreadPool 这两个方法就安全了,这两种方式创建的最大线程数可能是Integer.MAX_VALUE,而创建这么多线程,必然就有可能导致 OOM

正确使用:
这种情况下,一旦提交的线程数超过当前可用线程数时,就会抛出java.util.concurrent.RejectedExecutionException,这是因为当前线程池使用的队列是有边界队列,队列已经满了便无法继续处理新的请求。但是异常(Exception)总比发生错误(Error)要好。
但是部分alibaba作者更推荐使用guava创建对应的线程池,示例如下:
通过上述方式创建线程时,不仅可以避免 OOM 的问题,还可以自定义线程名称,更加方便的出错的时候溯源。
3.Arrays.asList之后不要调用修改操作
因为asList返回的实际是一个Arrays内部类,并没有实现集合的修改方法(add/remove/clear)// 当操作修改方法时,会报UnsupportedOperationException。
第一种情况:list.add("yangguanbao"); 运行时异常。
第二种情况:str[0] = "gujin"; 那么 list.get(0)也会随之修改。[涉及栈堆指针操作,修改数组的数据,导致同样引用该数据的list值被改变]

stack

heap

wu

list

str[o]"haha";

youhaha

str


4.使用 entrySet 遍历 Map 类集合 KV
说明:keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出key 所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。
如果是 JDK8,使用 Map.foreach 方法。
正例:values()返回的是 V 值集合,是一个 list 集合对象;keySet()返回的是 K 值集合,是一个 Set 集合对象;entrySet()返回的是 K-V 值组合集合。
5.SimpleDateFormat不要定义为static
SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为static,必须加锁,或者使用 DateUtils 工具类。
正例:注意线程安全,使用 DateUtils。亦推荐如下处理:

Java

运行代码复制代码

1

2

3

4

5

6

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {

@Override

protected DateFormat initialValue() {

return new SimpleDateFormat("yyyy-MM-dd");

}

};

说明:如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。
6.并发修改同一记录时需要加锁
要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。
说明:如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于 3 次

相关文章
|
Linux iOS开发 开发者
探索FFmpeg:实现自定义播放速度的全方位指南(一)
探索FFmpeg:实现自定义播放速度的全方位指南
1989 0
|
11月前
|
uml C语言
系统时序图
时序图是UML中描述对象间消息传递时间顺序的交互图,横轴为对象,纵轴为时间。用于展示交互流程、强调时序关系,直观呈现并发过程。主要元素包括角色、对象、生命线、控制焦点和消息等,广泛应用于系统动态建模。
系统时序图
|
3月前
|
人工智能 运维 自然语言处理
Geo专家于磊解析:GEO优化的基础、提升与突破
本文揭示生成式AI正重塑信息获取方式:用户不再点击链接,而是直接获取合成答案。GEO(生成式引擎优化)由此诞生——它不优化网页排名,而优化内容被AI采信、引用与复述的能力。Geo专家于磊提出“基础—提升—突破”三层框架,强调可信前提、可引用性、结构清晰是地基,数据支撑与答案岛是杠杆,实体网络与全域信任方达上限。
313 1
|
11月前
|
存储 Java 编译器
Java泛型类型擦除以及类型擦除带来的问题
本文详解Java泛型的类型擦除机制及其带来的问题。介绍泛型擦除后保留的原始类型、编译时类型检查原理、自动类型转换、与多态的冲突、静态成员限制等核心问题,并结合代码示例说明其底层实现和解决方案,帮助深入理解Java泛型的本质与局限性。(238字)
|
7月前
|
人工智能 文字识别 JavaScript
AI大模型开始“接管测试”:文本、语音、视觉,谁才是效率杀手锏?
本文揭秘AI大模型如何重塑测试效能:文本模型自动生成用例与脚本,语音模型实现录屏转问题、语音交互自动化,视觉模型突破UI识别与图像对比。三类模型协同构建多模态智能测试体系,助测试工程师从“手工对抗工具”转向“高效校验AI输出”,抢占质量保障新高地。
|
7月前
|
存储 人工智能 缓存
企业模型成本治理:从“任务分层”到“AI网关”,5个结构抓手告别账单失控
企业大模型成本失控,根源常在任务混用、上下文冗余、失败无界等结构性问题。本文提出五大治理抓手:任务分层路由、上下文复用、失败预算管控、Batch批处理、统一观测体系,并强调需通过标准化治理层实现成本从“月底追溯”到“日常可控”的转变。
352 5
|
10月前
|
人工智能 机器人 物联网
提高商店客流量的智能设备选型指南:从客流分析到数字化运营
实体零售面临客流下滑与运营瓶颈,亟需从“坐商”转向“数据驱动+主动引流”。本文系统解析六大类智能设备技术架构,涵盖客流分析、智能引流、智慧收银、导视系统、数据中台与氛围营造,结合不同业态痛点提供选型策略与实施路径,助力门店实现数字化升级与效率跃迁。
|
人工智能 自然语言处理 数据可视化
实践教程|如何创建一个WhatsApp AI Chatbot
无需代码!使用阿里云百炼 + Chat App 消息服务,10 分钟创建 WhatsApp AI 聊天机器人,支持企业知识库问答
1493 0
|
人工智能 前端开发 Java
Java 转 AI 不用慌!3 周求职打卡表,帮你按天推进、高效拿 offer
三周(21天)AI应用工程师转型打卡计划,涵盖Python基础、Prompt工程、实战项目与面试准备,每日明确任务目标,助力系统学习与进度追踪。
922 7
|
算法 关系型数据库 数据挖掘
SoccerNet 2025挑战赛:赛题整理(四)
梳理SoccerNet 2025挑战赛中的赛题四、以及该赛题的比赛结果
590 0

热门文章

最新文章