一、饿汉模式
public class Singleton {
//饿汉模式
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton;
}
}
在类被加载的时候创建对象。
优点:线程安全,保证对象只被创建一次。
缺点:不能延迟加载。
二、懒汉模式
public class Singleton {
//懒汉模式
private static Singleton singleton = null;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}
在对象需要的时候被创建,不会造成内存的浪费。缺点:不是多线程安全,多个线程访问可能会创建多个对象。
三、线程安全懒汉模式
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
}
对象创建增加同步锁,保证多线程线程安全,缺点:效率底下。所有的线程获取实例对象都会阻塞在方法外等待上一个线程执行完毕。
线程同步要注意Android ANR异常
四、优化效率,双重检查锁
public class Singleton {
private static volatile Singleton singleton = null;
private Singleton(){
}
public static Singleton getInstance() {
if(singleton ==null)
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
return singleton;
}
}
在单例模式中去new一个实例的情况比较少,绝大多数情况都是可以并行的读取对象操作。这里一定要加上volatile关键字,否则双重检查锁有可能会失效,导致有可能不止创建一个对象。
volatile
可见性: 一个线程改变了变量的值,另外的线程是马上可见的。
时序性 :禁止进行指令重排序。
五、静态内部类实现单例
public class SingletonStatic {
private SingletonStatic(){
}
public static SingletonStatic getInstance(){
return Singletonholder.singletonStatic;
}
private static class Singletonholder{
private static SingletonStatic singletonStatic = new SingletonStatic();
}
}
既可以做延迟加载,同时静态内部类里的实例化由JVM保证了线程安全。
六、枚举方式现实单例
public class SingletonEnumm {
private SingletonEnumm(){
}
public static SingletonEnumm getInstance(){
return Singleton.INSTANCE.getSingletonEnumm();
}
private enum Singleton{
INSTANCE;
private SingletonEnumm singletonEnumm;
//JVM保证只执行一次
private Singleton(){
singletonEnumm = new SingletonEnumm();
}
public SingletonEnumm getSingletonEnumm(){
return singletonEnumm;
}
}
}
6种单例的写法,4、5、6都有比较不错的性能。
扩展:
1、防止反射机制破坏单例
2、防止反序列化破坏单例