设计模式--创建模式--单例模式--java
2013-01-15 15:05
337 查看
Intent:
•Ensurea class only has one instance, and provide a global point of access to it.确保一个类只有一个实例,并且提供一个全局的引用来获取它。
Applicability
•theremust be exactly one instance of a class, and it must be accessible to clientsfrom a well-known access point.•仅有一个实例,并且客户端需要从一个众所周知的访问点来获取它。
•whenthe sole instance should be extensible bysubclassing, and clients should be able to use an extended instancewithout modifying
their code.
•当这个唯一实例应该通过子类化可扩展的,并且客户端应该无需更改代码就能使用一个扩展的实例时。
Consequences
•Controlled access to sole instance•控制实例访问
•Reduced name space
•减少名空间
•Permits refinement of operations and representation
•允许对操作和表示的精化
•Permits a variable number of instances
•允许可变数数目的实例
•More flexible than class operations
•比类操作更灵活
UML
Code
饿汉方式实现。当隐式加载Singleton,变初始化singleton。/** * 饿汉 * * @author changsheng */ public class Singleton { static private final Singleton singleton = new Singleton(); private Singleton(){ } static public Singleton getInstance() { return singleton; } }
利用反射破坏单例
@SuppressWarnings("unchecked") public static void reflect() throws InstantiationException, IllegalAccessException, InvocationTargetException { Class<Singleton> clazz = Singleton.class; /* get constructors info */ Constructor<?>[] methods = (Constructor<Singleton>[]) clazz .getDeclaredConstructors(); for (int i = 0; i < methods.length; i++) { System.out.println(methods[i]); } methods[0].setAccessible(true); Singleton s1 = (Singleton) methods[0].newInstance(); Singleton s2 = (Singleton) methods[0].newInstance(); System.out.println(s1 == s2); }
懒汉实现。当显式调用Singleton2.getInstance才初始化singleton2.
/** * 懒汉 * @author changsheng * */ public class Singleton2 { static private Singleton2 singleton2; private Singleton2(){ } //sychronized关键字不是必须的,根据需求而定。 static synchronized public Singleton2 getInstance(){ if(singleton2 == null){ singleton2 = new Singleton2(); } return singleton2; } }
懒汉和饿汉的选择主要以单例实例化是否耗时为衡量标准。
双重检查机制,主要解决多线程并发访问的效率。具体并发知识可查阅书籍Java Concurrency in practice。
class Singleton3 { static volatile private Singleton3 singleton3; /*此处为什么要使用volatile关键字?一旦线程改变了singleton3,其他线程可立即可见*/ private Singleton3(){ } /** * 为什么要使用双重检查机制?避免多个线程排队问题 */ static public Singleton3 getInstance(){ if(singleton3 == null){ synchronized (Singleton3.class) { if(singleton3 == null) singleton3 = new Singleton3(); } } return singleton3; } }
通过序列化来破坏单例。
public class Singleton3 implements Serializable { private static final long serialVersionUID = 1L; static private final Singleton3 s = new Singleton3(); private Singleton3(){ } static public Singleton3 getInstance(){ return s; } public static void main(String[] args) throws IOException, ClassNotFoundException { Singleton3 s1 = Singleton3.getInstance(); Singleton3 s2 = Singleton3.getInstance(); System.out.println(s1 == s2); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(s1); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); Singleton3 s3 = (Singleton3) ois.readObject(); System.out.println(s1 == s3); } }
java中实现单例最佳方式。具体细节查阅thinking in java
public enum Singleton { Instance; static public Singleton getInstance(){ return Instance; } public int method1(){ return 1; } public int method2(){ return 2; } }
可拓展的单例。
/** * * @author changsheng */ public class SingletonExtends { static private final SingletonExtends singleton = new SingletonExtends(); protected SingletonExtends(){ } static public SingletonExtends getInstance() { return singleton; } public void method(){ } }
public class SingletonExtendsEx extends SingletonExtends { static private final SingletonExtendsEx singleton = new SingletonExtendsEx(); static public SingletonExtendsEx getInstance() { return singleton; } private SingletonExtendsEx() { super(); } public void method1() { } public void method2() { } }
注意事项:在使用单例时,一定要保证确实只需要一个实例对象。
在javaWeb中,Servlet在什么时候是单实例,什么时候是多实例?为什么要做成单实例?
1、线程安全(当然在编写Servlet时候需要遵守一些约定,譬如servlet中尽量不要有共享的实例变量,如果有就需要进行并发控制)。
2、避免过多的垃圾对象。
相关文章推荐
- java设计模式【创建模式】之建造(Bulider)模式
- 剑指OFFER(java)-设计一个只能创建一个唯一实例的类——单例模式
- 设计模式--创建模式--抽象工厂模式--java
- JAVA设计模式学习之----创建模式:工厂模式(抽象工厂)
- java-设计模式-创建模式-原型模式prototype
- java设计模式--创建模式--工厂方法
- 设计模式--创建模式--工厂方法模式--java
- java设计模式 -------- 创建模式 之 单例模式【转】
- Java开发中的23种设计模式:创建类模式总结篇
- java学习笔记:面向对象编程之工具类的创建与单例设计模式
- java-设计模式-创建模式-建造者模式builder
- java 设计模式-创建模式之建造者模式
- java-设计模式-创建模式-单例模式singleton
- Java中如果把构造方法也私有化,如何创建对象?Java的单例设计模式——饿汉式和懒汉式区别
- Java 设计模式之单例模式的详解(创建模式)
- java设计模式 -------- 创建模式 之 抽象工厂模式
- java-设计模式-创建模式-工厂模式factory
- Java设计模式_创建模式_原型模式
- java 设计模式-创建模式之简单工厂模式
- java 设计模式-创建模式之单例模式