设计模式---单例模式
2023-03-14 22:36:13 时间
单例模式
单例模式的介绍
单例模式实现的八种方式
饿汉式
静态常量
步骤:
1.构造器私有化(防止new)
2.类的内部创建对象
3.向外暴露一个静态的公共方法—getInstance
//饿汉式静态常量
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态常量
private final static Singleton instance=new Singleton();
//提供一个公有的静态方法,返回一个实例对象
public static Singleton getInstance()
{
return instance;
}
}
public class Main
{
public static void main(String[] args)
{
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
静态常量的优缺点
静态代码块
//饿汉式静态常量
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态常量
private static Singleton instance;
//在静态代码块中,创建单例对象
static
{
instance=new Singleton();
}
//提供一个公有的静态方法,返回一个实例对象
public static Singleton getInstance()
{
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
静态代码块的优缺点
懒汉式
线程不安全的写法
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态常量
private static Singleton instance;
//提供一个公有的静态方法
//当使用该方法时,才去创建实例对象
//即懒汉式
public static Singleton getInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
优缺点
线程安全,同步锁—效率低,不推荐
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态常量
private static Singleton instance;
//提供一个公有的静态方法
//当使用该方法时,才去创建实例对象
//即懒汉式
//给当前静态方法加上一个同步锁,这样所有的对象就是一把锁
//多个对象同时调用此方法,会按顺序依次调用
public static synchronized Singleton getInstance()
{
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
优缺点
线程安全,同步代码块—无法解决线程安全问题,不推荐
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态常量
private static Singleton instance;
//提供一个公有的静态方法
//当使用该方法时,才去创建实例对象
//即懒汉式
public static Singleton getInstance()
{
if(instance==null)
{
//锁的是代码块
//锁的对象是当前类的字节码文件对象,即当前类的所有势力对象拥有一把锁
synchronized(Singleton.class)
{
instance=new Singleton();
}
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
优缺点
双重检查—解决线程安全和懒加载问题–推荐使用
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态常量
//volatile 保证变量在多线程下的可见性,即每个线程获取到当前变量的值是最新的值
private static volatile Singleton instance;
//提供一个公有的静态方法
//当使用该方法时,才去创建实例对象
public static Singleton getInstance()
{
//加入双重检查问题,解决线程安全,同时解决懒加载问题
if(instance==null)
{
//锁的是代码块
//锁的对象是当前类的字节码文件对象,即当前类的所有势力对象拥有一把锁
synchronized(Singleton.class)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
优缺点
静态内部类—可以实现懒加载,线程安全,推荐使用
静态内部类在调用时,才会加载
当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的
class Singleton
{
//构造器私有化,外部不能new
private Singleton(){}
//静态内部类
private static class SingletonInstance{
//静态属性
private static final Singleton INSTANCE=new Singleton();
}
public static Singleton getInstance()
{
//该方法调用时,静态内部类加载,里面的静态属性才会赋值
return SingletonInstance.INSTANCE;
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
优缺点
枚举
enum Singleton
{
//枚举常量
INSTANCE;
//底层: public static final Singleton INSTANCE= new Singleton ();
//方法
public void getInstance()
{
System.out.println("得到实例");
}
}
public class Main
{
public static void main(String[] args) {
Singleton s1=Singleton.INSTANCE;
Singleton s2=Singleton.INSTANCE;
s1.getInstance();
s2.getInstance();
System.out.println(s1.hashCode()==s2.hashCode());
}
}
优缺点
单例模式注意事项
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的