参考菜鸟博客,网址:http://www.runoob.com/design-pattern/singleton-pattern.html
https://blog.csdn.net/yeyazhishang/article/details/90445330
类加载顺序
类加载(classLoader)机制一般遵从下面的加载顺序
如果类还没有被加载:
1先执行父类的静态代码块和静态变量初始化,静态代码块和静态变量的执行顺序跟代码中出现的顺序有关。
2执行子类的静态代码块和静态变量初始化。
3执行父类的实例变量初始化
4执行父类的构造函数
5执行子类的实例变量初始化
6执行子类的构造函数
单例模式:当您想控制实例数目,节省系统资源的时候。
应用实例:windows是多进程多线程,在操作文件时可能有多个进程或者线程同时操作一个文件,所以,所有的文件必须通过唯一的实例来进行。
如果一个类或者方法被static修饰,则会被类的所有实例共享,只要这个类被加载,该成员变量或方法就可以通过类名去进行访问,它的作用用一句话来描述就是,不用创建对象就可以调用方法或者变量。
我们将创建一个 SingleObject 类。SingleObject 类有它的私有构造函数和本身的一个静态实例。
SingleObject 类提供了一个静态方法,供外界获取它的静态实例。SingletonPatternDemo,我们的演示类使用SingleObject 类来获取 SingleObject 对象。
饿汉式 (可用)
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return INSTANCE;
}
}
普通的懒汉式 (线程不安全,不可用)
public class Singleton {
private static Singleton instance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
实例1
public class SingleObject {
//创建 SingleObject 的一个对象
private static SingleObject instance = new SingleObject();
//让构造函数为 private,这样该类就不会被实例化
private SingleObject(){} //此方法阻止了,该类被实例化,即不可 SingleObject object = new SingleObject();
//获取唯一可用的对象
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
class SingleObject {
//创建 SingleObject 的一个对象
private static SingleObject instance = new SingleObject();
//让构造函数为 private,这样该类就不会被实例化
private SingleObject(){} //此方法阻止了,该类被实例化,即不可 SingleObject object = new SingleObject();
//获取唯一可用的对象
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
获取:
public class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 SingleObject() 是不可见的
//SingleObject object = new SingleObject();
//获取唯一可用的对象
SingleObject object = SingleObject.getInstance();
//显示消息
object.showMessage();
}
}
class SingletonPatternDemo {
public static void main(String[] args) {
//不合法的构造函数
//编译时错误:构造函数 SingleObject() 是不可见的
//SingleObject object = new SingleObject();
//获取唯一可用的对象
SingleObject object = SingleObject.getInstance();
//显示消息
object.showMessage();
}
}
几种实现方式:
1懒汉式
线程不安全
public class Singleton {
private static Singleton instance; //实例化,在需要时才实例化,故懒
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
线程安全-加锁,保证了单例,但加锁影响效率
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() { //添加锁
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
二。饿汉式
线程安全-无锁,执行效率高
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
三、双检锁/双重校验锁(DCL,即 double-checked locking)
线程安全,且运行效率高
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
双重检查懒汉式 (可用,推荐)
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}