说说单例模式
来源:互联网 发布:java整形转换为字符串 编辑:程序博客网 时间:2024/06/09 13:02
单例模式应该都不陌生,被广泛使用的设计模式之一,在应用这个模式时,单例对象的类必须保证只有一个实例存在。
下面将会为大家介绍几种单例实现的方式,虽然实现方式有差异,但是核心原理都是:
1、将构造函数私有化
2、通过静态方法获取一个唯一的实例
3、在获取过程中保证线程安全
4、防止反序列化导致重新生成实例对象
线程不安全的单例
这种实现方式是线程不安全的,非常不推荐这种做法
public class Signleton {private static Signleton signleton;private Signleton() {}/** * 第一中方式:缺点,多线程访问时不安全 * * @return */public static Signleton getInstance() {if (signleton == null) {signleton = new Signleton();}return signleton;}/** * 加入该方法杜绝在反序列化时重写生成对象 * * @return * @throws ObjectStreamException */private Object readResolve() throws ObjectStreamException {return signleton;}}
线程安全的单例
这种方式是线程安全的,但是每次访问getInstance()方法时都会进行同步控制,效率低
public class Signleton {private static Signleton signleton;private Signleton() {}/** * 第二中方式 加上同步关键字,解决了多线程访问安全的问题 * 缺点:会降低性能,因为一旦设置好signleton变量,就不需要同步了,之后每次调用该方法会降低性能 * * @return */public static synchronized Signleton getInstance() {if (signleton == null) {signleton = new Signleton();}return signleton;}/** * 加入该方法杜绝在反序列化时重写生成对象 * * @return * @throws ObjectStreamException */private Object readResolve() throws ObjectStreamException {return signleton;}}
双重锁的单例模式
该方式避免了每次调用getInstance()方法都进行同步控制
public class Signleton {private static Signleton signleton;private Signleton() {}/** * 第三种方式, 双重检查加锁,首先检查实例是否已经创建,如果未创建才进行同步控制, * 这样只有第一次会同步,提高了性能 * * @return */public static Signleton getInstance() {if (signleton == null) {synchronized (Signleton.class) {if (signleton == null) {signleton = new Signleton();}}}return signleton;}/** * 加入该方法杜绝在反序列化时重写生成对象 * * @return * @throws ObjectStreamException */private Object readResolve() throws ObjectStreamException {return signleton;}}但是由于signleton=new Signleton()不是原子操作,由于线程调度的原因会在某些情况下出现失效的问题,不过只需要加上volatile即可(private volatile static Signleton signleton;)。
饿汉单例模式
该方式会在类加载时就初始化signleton。
public class Signleton { private static Signleton signleton=new Signleton();//对应第四中方式private Signleton() {} /** * 第四种方式,如果应用程序总是创建并使用单例实例,可以在镜头初始化器中创建单例, 使用时直接返回 * * @return */public static Signleton getInstance() {return signleton;}/** * 加入该方法杜绝在反序列化时重写生成对象 * * @return * @throws ObjectStreamException */private Object readResolve() throws ObjectStreamException {return signleton;}}
静态内部类单例模式
该模式在类加载时不会初始化signleton,只有在调用get方法时才初始化
public class Signleton {/** * 第五种方式,使用静态内部类实现单例,相比饿汉模式不会在第一次加载Signleton类时就初始化sInstance, * 只有在调用getInstance时才会初始化 */public static Signleton getInstance() {return SignletonHolder.sInstance;}private static class SignletonHolder {private static final Signleton sInstance = new Signleton();}/** * 加入该方法杜绝在反序列化时重写生成对象 * * @return * @throws ObjectStreamException */private Object readResolve() throws ObjectStreamException {return SignletonHolder.sInstance;}}
枚举单例
该方式写法简单,且默认枚举实例的创建时线程安全的,并且在任何情况下它都是一个单例
public enum SingletonEnum {INSTANCE;// TODO 一些类的方法public void doSomthing() {}}
阅读全文
1 0
- 说说单例模式
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- spark-streaming 读取kafka的方式
- 51Nod-1085-背包问题
- springboot + mongodb 查询实例
- vs2017无法查找或打开 pdb 文件
- microsoft visual c++ 6.0中文版两种使用方法
- 说说单例模式
- 关于springMVC无法加载静态资源的问题
- springMVC原理(二):SpringMVC核心分发器DispatcherServlet分析[附带源码分析]
- 530_自定义彩色进度条SeekBar
- 字符串问题---回文最小分割数
- win10安装PowerDesigner16.5报错:An error[-5001 ... 的解决办法
- “想好了就做,没想好就快速迭代”
- [笔记分享] [Build] Android编译系统的Android.mk
- 我了解到的JavaScript异步编程