设计模式-单例(Singleton)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式-单例(Singleton)相关的知识,希望对你有一定的参考价值。
2018-1-12 by Atlas
- UML
- UML中加“-”表示私有的(private);
- UML中加“+”表示公有的(public);
- UML中加“_”表示静态的(static)。
Singleton模式基本构成:
- 静态的私有的类成员变量singleton,私有的表示只有成员所生存的对象可以访问,静态的表示类加载准备阶段分配初始值、解析阶段字符引用转化为直接引用;
- 私有的类构造方法Singleton,私有的构造方法表示禁止非Singleton类调用实例构造器创建对象实例;
- 静态的公有的类方法getInstance,静态的类方法表示类加载解析阶段就从字符引用转化为直接引用,即内存中方法的实际地址,可以通过类.方法直接调用。
- 应用场景
(1)如果有1个以上的对象实例时,由于对象实例彼此之间的影响,可能会发展成出乎意料的BUG。
(2)需要控制类的对象实例的数量,以降低资源的使用时。
- 标准示例
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() {
System.out.println("已产生对象实例。");
}
public static Singleton getInstance() {
return singleton;
}
}
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
- 拓展示例
延迟对象实例化
- 优点:
类加载时不进行目标对象的实例化操作,提高了类加载的速度,实际访问需要时才进行目标对象的实例化。- 缺点:
相比类加载时就进行目标对象实例化,延迟实例化可能导致多线程并发时产生线程安全问题,需要同步访问入口方法以达到线程安全的目的,理论上降低了多线程并发访问的效率。
public class Singleton {
private static Singleton singleton;
private Singleton() {
System.out.println("已产生对象实例。");
}
public static synchronized Singleton getInstance() {
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2);
}
那么问题来了,有没有一种两全其美的方式呢,答案是有的。
静态内部类实例化
- 优点:
(1)外部类加载时无须进行目标对象的实例化操作,提高了类加载的速度,实际访问需要时加载内部类并进行目标对象的实例化。
(2)静态内部类只会进行一次内部类的类变量的初始化,不会产生线程安全问题,无须同步,不会降低多线程并发访问效率。
public class Singleton {
private Singleton() {
System.out.println("已产生对象实例。");
}
private static class SingletonHolder {
private static Singleton singleton = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.singleton;
}
}
- 案例鉴赏
java.lang.Runtime#getRuntime()
public class Runtime {
private static Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.
* Most of the methods of class <code>Runtime</code> are instance
* methods and must be invoked with respect to the current runtime object.
*
* @return the <code>Runtime</code> object associated with the current
* Java application.
*/
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don‘t let anyone else instantiate this class */
private Runtime() {}
// 忽略其他
}
以上是关于设计模式-单例(Singleton)的主要内容,如果未能解决你的问题,请参考以下文章