mac_girl

设计优化之单例模式

单例模式

定义: 对象创建模式,确保系统中一个类只产生一个实例

使用单例的好处:

1): 对频繁使用的对象,省略创建对象所花费的时间

2):new 操作次数的减少,对系统内存的使用频率也会降低,减轻GC压力,缩短GC停顿时间。

创建单例模式

第一种方式):类一加载就创建

public class Singleton {
/**
私有化构造方法,外界不能通过new运算符创建对象
*/
private Singleton(){
System.out.println("create singleton");
}

/**
* 实例化Singleton对象,static修饰,在类加载时实例化
*/
private static Singleton instance = new Singleton();

/**
* 提供一个接口,外界可以通过该接口获取Singleton对象
*/
public static Singleton getInstance(){
return instance;
}
}

弊端:在使用单例类时,不管有没有使用单例对象,单例变量都会通过new运算符实例化。

public class Singleton {
/**
私有化构造方法,外界不能通过new运算符创建对象
*/
private Singleton(){
System.out.println("create singleton");
}

/**
* 实例化Singleton对象,static修饰,在类加载时实例化
*/
private static Singleton instance = new Singleton();

/**
* 提供一个接口,外界可以通过该接口获取Singleton对象
*/
public static Singleton getInstance(){
return instance;
}

public static void getString(){
System.out.println("ceateString in Singleton");
}
}

//执行Singleton.getString()程序输出
create singleton
ceateString in Singleton
//不管有没有使用单例对象,单例变量都会通过new运算符实例化

第二种方式):延迟加载

先将单例变量声明为null,只有使用单例对象时,才通过new运算符创建实例

public class LazySingleton {
/**
声明私有的构造器
*/
private LazySingleton(){
System.out.println("create lazySingleton");
}

/**
* 单例变量初始化时不进行实例化
*/
private static LazySingleton instance = null;

/**
* 1)提供获取单例对象的接口
* 2)加锁:
* 防止线程1在未赋值前,线程2可能判断instance == null,此时会产生两个单例对象
* @return
*/
public static synchronized LazySingleton getInstance(){
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}

弊端:多线程调用时可能会产生两个单例对象,使用了sychonized可以预防该现象出现,但时耗远远大于第一种模式

第三种方式):使用私有的静态成员内部类的方式

public class StaticSingleton {
/**
* 将构造方法私有化
*/
private StaticSingleton(){
System.out.println("create staticSingleton");
}

/**
* 创建静态成员内部类,在内部类中创建单例对象
* --:静态成员内部类在外部类加载时不会加载,只有在调用时才会加载
*/
private static class SingletonHolder{
private static StaticSingleton instance = new StaticSingleton();
}

/**
* 提供获取单例的接口
* ---:满足了只有在使用单例时才使用new进行实例化,也不必使用synchonized关键字
*/
public static StaticSingleton getInstance(){
return SingletonHolder.instance;
}

public static void get(){
System.out.println("get");
}
}

好处:解决了延迟加载的问题,单例可以在使用时创建,也不必使用synchonized关键字

posted on 2019-09-17 20:01  宇宙美少女  阅读(200)  评论(0)    收藏  举报

导航