单例模式通俗的说就是在一个应用程序中某一个类的对象是唯一的,无论在哪里操作这个对象都是操作的同一个对象。本篇不仅介绍关于单例模式的两种类型,而且介绍实际开发中常使用的具体实现方法。
单例模式分成两种类型,分别是饿汉模式和懒汉模式。
饿汉模式
饿汉模式是创建了一个静态对象并且直接提供到外部。 由于静态对象是在类加载的时候就创建了,并不一定是在使用的时候才创建,所以称之为饿汉模式。
/**
* @author BeautifulSoup
* 单例模式的饿汉模式
*/
public class Singleton {
//构造方法私有化
private Singleton(){
}
//创建类的唯一实例
private static Singleton singleton=new Singleton();//类加载的时候就创建实例,
//提供用于获取实例的方法
public static Singleton getInstance(){
return singleton;
}
}
懒汉模式 懒汉模式与饿汉模式的区别在于在定义一个对象的时候,并不直接实例化,只有当使用该对象的时候才会创建实例对象。
public class Singleton {
private Singleton(){
}
private static Singleton singleton;//仅仅声明实体并不实例化
public static Singleton getInstance(){
if(null==singleton){
singleton=new Singleton();
}
return singleton;
}
}
因此,饿汉模式是加载类的时候比较慢,运行时获取对象的速度比较快,并且饿汉模式是线程安全的;而懒汉模式是加载类的时候比较快,运行时获取对象的速度比较慢,并且懒汉模式线程是不安全的。
通过上面的介绍也可以知道,对于饿汉模式和懒汉模式,两者都有利弊。所以在实际开发中必然需要有一种更好的实现方法。
对于饿汉模式的优化-------使用静态内部类:
public class Singleton {
private static class Holder{
private static final Singleton instance=new Singleton();
}
public static Singleton getInstance(){
return Holder.instance;
}
}
对于懒汉模式的优化-----线程安全的检查锁:
public class DoubleCheck {
private volatile static DoubleCheck ins;//volatile能够起到禁止指令的重排序优化的作用
private DoubleCheck(){
}
public static DoubleCheck getInstance(){
if(null==ins){ //检查
synchronized(DoubleCheck.class){
if(null==ins){
ins=new DoubleCheck();
}
}
}
return ins;
}
}