设计模式之单例模式(Java)
来源:互联网 发布:程序员修改bug搞笑图 编辑:程序博客网 时间:2024/06/06 18:34
设计模式之单例模式(Java)
- 设计模式之单例模式Java
- 概念
- 特点
- 实现
- 问题与总结
概念
Java单例模式是一种常见的设计模式,其主要作用是保证在Java程序中,某个类只有一个实例(对象)存在,某些管理 器和控制器常被设计成单例模式。
特点
1. 单例类只能有一个实例。 2. 单例类的实例必须由该单例类自行创建。 3. 单例类必须为所有其他对象提供这一实例。
实现
1. 懒汉式(非线程安全) public class Singleton1 { private Singleton1() {} private static Singleton1 instance = null; public static Singleton1 getInstance() { if (instance == null) { instance = new Singleton1(); } return instance; } } Singleton1类通过将构造方法修饰符限制为private,防止被其他外部类实例化,它的唯一实例只能通过 getInstance()方法获得(通过Java反射机制可以访问类的私有方法并实例化,此处暂不讨论)。该单例模 式为懒汉式单例,并没有考虑到并发环境下的线程安全问题,故并发环境下有可能出现多个实例。 2. 懒汉式(线程安全) public class Singleton2 { private static Singleton2 instance; private Singleton2() {} public static synchronized Singleton2 getInstance() { if (instance == null) { instance = new Singleton2(); } return instance; } } 这种实现方式能够在并发环境中线程安全,并且实现了懒加载。但是效率很低,大多数情况下是不需要同步的。 3. 饿汉式 public class Singleton3 { private static Singleton3 instance = new Singleton3(); private Singleton3() {} public static Singleton3 getInstance() { return instance; } } 这种基于类加载机制能够保证在并发环境中线程安全,没有实现懒加载。但是,该实例在类加载过程中就实例 化,而大多数情况下都是调用getInstance()方法之后才使用该实例,并不需要在类加载时初始化该实例。 4. 饿汉式-变种 public class Singleton4 { private static Singleton4 instance = null; static { instance = new Singleton4(); } private Singleton4() {} public static Singleton4 getInstance() { return instance; } } 这种实现方式会在第一次类加载时初始化实例,与方法3一般无二。 5. 懒汉式-双重校验锁 public class Singleton5 { private volatile static Singleton5 singleton; private Singleton5() {} public static Singleton5 getSingleton() { if (singleton == null) { synchronized (Singleton5.class) { if (singleton == null) { singleton = new Singleton5(); } } } return singleton; } } 这是第2中实现方式的升级,这种实现方式基本可以解决线程安全,但是有个别情况无法保证线程安全(此处暂 不讨论)。 6. 懒汉式-静态内部类 public class Singleton6 { private static class LazyHolder { private static final Singleton6 INSTANCE = new Singleton6(); } private Singleton6() {} public static final Singleton6 getInstance() { return LazyHolder.INSTANCE; } } 这种方式利用了JVM的类加载机制来保证初始化实例时的线程安全问题,但是它与方法3、4的区别是:方法3、 4只要在Singleton类被装载时instance就会被实例化。而方法6的Singleton类被装载时,LazyHolder并没有被 主动引用,所以不会实例化instance,当调用getInstance()方法时,LazyHolder被主动引用,故需要实例 化instance,这种方式既保证了实例懒加载,又保证了线程安全问题,相对比较合理。
问题与总结
**问题** 问题1 如果单例由不同的类装载器装入,便有可能存在多个实例。例如,某些servlet容器对每个servlet使 用完全不同的类装载器,如果有两个servlet访问一个单例类,就会有各自的实例。 问题2 如果Singleton类实现了java.io.Serializable接口,该实例可能被序列化和反系列化。则反序列化 的多个对象,就会存在多个实例。 问题2的解决方法在《Effective Java》这本书中有提,即重写readResolve()方法,具体如下: private Object readResolve() { return INSTANCE; } **总结** 单例模式为一个面向对象的应用程序提供了对象惟一的访问点,不管它实现何种功能,整个应用程序都应共享一 个实例对象。 对于单例模式的几种实现方式,需了解饿汉式和懒汉式的区别,线程安全与非线程安全的区别,类加载的时机, 以及懒汉式为了实现线程安全的几种方式的差别。
阅读全文
0 0
- java设计模式之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- java设计模式之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java模式设计之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- paperweekly 李纪为 对话机器人直播。
- Ubuntu16.04在Oracle VM的安装步骤
- C++基础(一)——大端存储和小端存储
- is not assignable to
- 首篇博客---接触虚拟机
- 设计模式之单例模式(Java)
- 2017年11月7日 第二十九次总结
- SpringBoot入门
- ArrayList、LinkedList、Vector的区别
- HDU-1022 火车进出站问题【栈】
- [置顶] 基于深度学习的色情视频鉴定
- SSL2839 2017年11月6日提高组T1 游戏(dp)
- Hdu 6227 Rabbits
- 百度