java设计模式之单例模式
说明
单例模式确保某一个类在应用和使用中从始至终只有一个只有一个实例
步骤:
(1)私有化该类的构造函数
(2)通过new在本类中创建一个本类对象
(3)定义一个公有的方法,将在该类中所创建的对象返回
单例模式的饿汉式[可用]
public class Singleton {
private static Singleton instance=new Singleton();
private Singleton(){};
public static Singleton getInstance(){
return instance;
}
}
单例模式的饿汉式变换写法[可用]
public class Singleton{
private static Singleton instance = null;
static {
instance = new Singleton();
}
private Singleton() {};
public static Singleton getInstance() {
return instance;
}
}
单例模式懒汉式双重校验锁[推荐用]
解释一下:
注意:
instance = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。
1.给 instance 分配内存
2.调用 Singleton 的构造函数来初始化成员变量
3.将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)
说白了,当第一个线程执行,instance = new Singleton()完这句代码,instance并不一定刷新到主内存,可能只是第一个线程的本地内存刷新了,然而线程间本地内存是不可见的,所以存在另外一个线程拿到会不一样,使用volatile 关键字将保证其可见性,synchronized 保证其原子性,这样才不会出现多线程问题
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;
}
}
内部类[推荐用]
package com.test.singleton;
/**
*
* Description:静态内部类 这种方式同样利用了classLoder的机制来保证初始化instance时只有一个线程
* 这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,
* 只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。
*类装载的机制来保证初始化实例时只有一个线程
*
* @author 2016年11月17日上午10:13:54
*/
public class Singleton3 {
// 内部类
public static class SingletonHolder {
private static final Singleton3 single = new Singleton3();
}
private Singleton3() {
}
public static final Singleton3 getInstance() {
return SingletonHolder.single;
}
}