1、单例模式:是一种常用的软件设计模式,属于创建型模式的一种。在应用这个模式时,单例对象的类必须保证只有一个实例存在。
2、实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。(维基百科)
3、实现方式
(1)懒汉式:线程不安全(一直等到对象实例化的时候才会创建,反映稍慢一些,而且在多线程不能正常工作。在多线程访问的时候,很可能会造成多次实例化,就不再是单例了。)
代码:class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
//这种方式只能在单线程下使用,如果在多线程下,一个线程进入了if判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句块,这样就会产生多个实例,违背了单例原则
(2)懒汉式:线程安全,使用同步方法,加入synchronized,只允许一个线程访问
代码:
class Singleton{
private static Singleton singleton;
private Singleton (){}
public static synchronized Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
(3)饿汉式:静态方法,线程安全,会造成内存浪费,在类装载的时候就创建,不管你用不用,先创建了再说
代码:
class Singleton{
private Singleton(){}
private final static Singleton instance = new Singleton ();
public static Singleton getInstance(){
return instance;
}
}
(4)饿汉式:静态代码块
代码:
class Singleton{
private Singleton(){}
private static Singleton instance;
static {
instance = new Singleton();
}
public static Singleton getInstance(){
return instance;
}
}
(5)双重检查:synchronized同步块里面能够保证只创建一个对象。但是通过在synchronized的外面增加一层判断,就可以在对象一经创建以后,不再进入synchronized同步块。这种方案不仅减小了锁的粒度,保证了线程安全,性能方面也得到了大幅提升。同时这里要注意一定要说volatile,这个很关键,volatile一般用于多线程的可见性,但是这里是用来防止指令重排序的
代码:
class Singleton{
private static volatile Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
(6)静态内部类:线程安全,效率高,静态内部类方式在Singleton类被加载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化,类的静态属性只会在第一次加载类的时候初始化
代码:
class Singleton{
private Singleton(){}
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
(7)枚举:而且无偿地提供了序列化机制,并由JVM从根本上提供保障,绝对防止多次实例化,是更简洁、高效、安全的实现单例的方式
代码:
enum Singleton{
INSTANCE;//属性
public void method(){
}
}