Java如何确保线程安全的单例模式_Java单例并发安全写法讲解
发布时间 - 2025-12-31 00:00:00 点击率:次Java线程安全单例首选静态内部类和枚举:静态内部类利用JVM类加载机制实现懒加载与天然线程安全;枚举由JVM保证原子性,兼具序列化与反射安全;DCL需volatile防重排序,易出错应慎用。
Java中确保线程安全的单例模式,核心在于防止多个线程同时创建实例。最推荐、最实用的方式是静态内部类(Static Inner Class)和枚举(Enum),它们天然线程安全、简洁高效,且能防止反射和反序列化破坏。
静态内部类写法——延迟加载 + 天然同步
利用JVM类加载机制:外部类加载时,内部类不加载;只有首次调用getInstance()时才触发内部类初始化,而JVM保证类初始化过程是线程安全的。
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
- ✅ 延迟加载(懒汉式),比饿汉式更节省资源
- ✅ 无需synchronized或volatile,无性能开销
- ✅ 反射无法绕过私有构造(new Singleton()会抛异常,因为Holder未初始化)
- ⚠️ 注意:不能在构造方法里调用
getInstance(),否则可能引发类初始化循环
枚举单例——最简最安全(JDK5+)
《Effective Java》强烈推荐。JVM保证枚举实例创建的原子性,且天然防止反射攻击和反序列化问题。
public enum Singleton {
INSTANCE;
public void doSomething() {
// 业务方法
}
}
- ✅ 写法极简,一行定义实例
- ✅ 线程安全、序列化安全、反射安全,一揽子解决
- ✅ 获取实例:
Singleton.INSTANCE(比方法调用更快) - ⚠️ 若需传参初始化(如配置对象),枚举不直接支持,此时优先选静态内部类
双重检查锁定(DCL)——慎用但需懂原理
曾是主流写法,但容易出错。关键点:必须用volatile禁止指令重排序,否则可能返回未初始化完成的对象。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton(); // 非原子操作:分配内存 → 初始化 → 赋值引用
}
}
}
return instance;
}
}
- ✅ 懒加载 + 同步粒度小(仅首次创建加锁)
- ❌ 忘加
volatile会导致严
重并发bug(罕见但真实存在) - ❌ 构造函数若抛异常,后续调用仍会重复尝试创建(可加try-catch+标记位修复,但更复杂)
其他方式对比说明
• 饿汉式(static final):类加载即创建,线程安全但不支持懒加载,可能浪费资源。
• 同步方法(synchronized getInstance):安全但每次调用都加锁,性能差,已淘汰。
• ThreadLocal:每个线程一个实例,不是“单例”,而是“每线程单例”,适用场景不同。
基本上就这些。日常开发首选静态内部类或枚举;追求极致安全又接受语法风格,直接用枚举;维护老代码遇到DCL,务必确认volatile是否存在。不复杂但容易忽略细节。
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
java获取注册ip实例
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
如何快速搭建安全的FTP站点?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
Laravel distinct去重查询_Laravel Eloquent去重方法
Laravel如何生成API文档?(Swagger/OpenAPI教程)
Laravel如何使用模型观察者?(Observer代码示例)
Laravel Seeder填充数据教程_Laravel模型工厂Factory使用
Android使用GridView实现日历的简单功能
Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)
SQL查询语句优化的实用方法总结
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
实例解析angularjs的filter过滤器
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法
如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程
如何用腾讯建站主机快速创建免费网站?
Laravel如何使用Service Container和依赖注入?(代码示例)
如何快速使用云服务器搭建个人网站?
利用vue写todolist单页应用
焦点电影公司作品,电影焦点结局是什么?
ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集
Laravel如何创建和注册中间件_Laravel中间件编写与应用流程
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
公司门户网站制作流程,华为官网怎么做?
Java垃圾回收器的方法和原理总结
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】
如何快速查询域名建站关键信息?
详解vue.js组件化开发实践
微信小程序 scroll-view组件实现列表页实例代码
百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧
佛山网站制作系统,佛山企业变更地址网上办理步骤?
浅析上传头像示例及其注意事项
如何为不同团队 ID 动态生成多个独立按钮
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】
Swift中switch语句区间和元组模式匹配
手机网站制作与建设方案,手机网站如何建设?
C++用Dijkstra(迪杰斯特拉)算法求最短路径
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
简单实现Android验证码
Laravel如何创建自定义Artisan命令?(代码示例)
今日头条AI怎样推荐抢票工具_今日头条AI抢票工具推荐算法与筛选【技巧】
上一篇:使用Yii作为微服务架构的后端
下一篇: ,都有哪些好的动漫网站?
上一篇:使用Yii作为微服务架构的后端
下一篇: ,都有哪些好的动漫网站?


重并发bug(罕见但真实存在)