欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > java设计模式(一)——单例模式

java设计模式(一)——单例模式

2024/10/24 12:29:14 来源:https://blog.csdn.net/print_out/article/details/140047626  浏览:    关键词:java设计模式(一)——单例模式

一、模式介绍

单例模式:
某一个类在系统中只需要有一个实例对象,而且对象由这个类自行实例化并提供给系统其他地方使用,这个类称为单例类。

使用场景:
1、处理资源访问的冲突
2、从业务概念上有些数据在系统中只应保存一份

特点:
某个类只能有一个实例,即使是在多线程运行环境下;
单例类的实例一定是单例类自身创建,而不是单例类外部用其他方式如new方式创建
单例类只需要提供一个方法想整个系统提供这个实例对象

分类:
单例模式分为饿汉模式和懒汉模式,
懒汉模式的意思就是这个类很懒,只要别人不找它要实例,它都懒得创建。
饿汉模式在初始化时,我们就创建了唯一的实例,即便这个实例后面并不会被使用。

二、代码实现

1、饿汉模式实现

/*** 饿汉模式* 使用静态常量在类加载前创建实例,其线程是安全的,有jvm保证其线程安全*/
public class HungrySingleton {private static final HungrySingleton instance = new HungrySingleton();//构造函数定义为私有,防止外部创建实例private HungrySingleton(){}// 系统使用单例的入口public static HungrySingleton getInstance(){return instance;}
}

2、懒汉模式实现

2.1、经典懒汉模式
/*** 经典单例模式,只适用于单线程,线程不安全*/
// 懒汉模式
public class LayzSingleton01 {private static LayzSingleton01 instance;//构造函数定义为私有,防止外部创建实例private LayzSingleton01(){}//系统使用单例的入口public static LayzSingleton01 getInstance(){if(instance==null){return new LayzSingleton01();}return instance;}
}
2.2、线程安全懒汉模式
/*** 懒汉模式,* 添加 synchronized 保证线程安全,单会拖延效率* 高并发下多个线程区获取这个实例,需要排队。*/
// 懒汉模式
public class LayzSingleton02 {private static LayzSingleton02 instance;//构造函数定义为私有,防止外部创建实例private LayzSingleton02(){}//系统使用单例的入口public static synchronized LayzSingleton02 getInstance(){if(instance == null){return new LayzSingleton02();}return instance;}}
2.3、优化效率懒汉模式
/*** 懒汉模式,添加synchronized代码块解决效率问题,但是此情况还是会出现线程不安全情况* 假设我们有两个线程 T1与T2并发访问getInstance方法。* 当T1执行完if (instance == null)且instance为null时,其CUP执行时间被T2抢占,所以T1还没有创建实例。* T2也执行if (instance == null),此时instance肯定还为null,T2执行创建实例的代码,* 当T1再次获得CPU执行时间后,其从synchronized 处恢复,又会创建一个实例。*/// 懒汉模式
public class LayzSingleton03 {private static LayzSingleton03 instance;//构造函数定义为私有,防止外部创建实例private LayzSingleton03(){}//系统使用单例的入口public static LayzSingleton03 getInstance(){if(instance==null){synchronized (LayzSingleton03.class){instance = new LayzSingleton03();}}return instance;}
}
2.4、double-check懒汉模式
/*** 懒汉模式,double-check 保证线程安全和效率* 这种单例的写法做了两次 if (null == instance)的判断,因此被称为double-check的方式。* 第一次check为了提高访问性能。因为一旦实例被创建,后面线程的所有的check都为假,不需要执行synchronized竞争锁了。* 第二次check是为了线程安全,确保多线程环境下只生成一个实例。* 需要注意的是,这种方式,在定义实例时一定需要加上volatile 关键字,禁止虚拟机指令重排,* 否则,还是有一定几率会生成多个实例,关于volatile 关键字和指令重排的问题请自行百度,*/// 懒汉模式
public class LayzSingleton04 {//注意加上volatile关键字private static volatile LayzSingleton04 instance;//构造函数定义为私有,防止外部创建实例private LayzSingleton04(){}//系统使用单例的入口public static LayzSingleton04 getInstance(){//第一次检查提高访问性能if(instance==null){synchronized (LayzSingleton04.class){//第二次检查为了线程安全if(instance==null){instance = new LayzSingleton04();}}}return instance;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com