单例模式
单例模式定义:确保系统中一个类只有一个实例
单例模式的作用:确保某些对象只有一个,比如线程池,缓存,注册表等等。
1.饿汉模式
首先,私有化默认构造方法,使得外界无法通过默认构造函数实例化对象
然后再类中直接实例化一个私有对象,同样,外界无法访问。再定义一个公有的类函数,使外界能通过GetInstance函数获得该私有对象。
/**
* 单例模式 (一) 饿汉模式
* @author Superman
*
*/
public class Singleton {
//第一步 私有化默认构造方法,使外界不能直接调用默认构造方法实例化
private Singleton(){}
//第二步 实例化私有对象
private static Singleton singleton=new Singleton();
//第三步 定义一个 getInstance
public static Singleton GetInstance(){
return singleton;
}
}
通过测试类来证明
比较结果为ture,可见实例化的两个对象singleton跟singleton2的对象是一样的。
public class TestSingleton {
public static void main(String[] args) {
Singleton singleton = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance();
System.out.println(singleton.equals(singleton2));
}
}
优点:线程安全,因为在类中就已经实例化好了对象,只是通过函数对外开放,使外界可得。并且在类加载时就已经实例化好了对象,使用很快速。
缺点:如果外界没有使用到这个对象的话,就造成了资源的浪费。
2.懒汉模式
与饿汉模式的区别就在于,懒汉模式仅仅是在类中声明了私有对象,并没有对其进行实例化。而是在外界调用GetInstance获取实例是才进行判断,如果singleton为空,则为其实例化一个对象。如果不为空,则说明对象已经实例化,直接返回即可。
public class Singleton2 {
//第一步 私有化默认构造方法,是外界不能直接调用默认构造方法实例化
private Singleton2(){}
//第二步 实例化私有对象
private static Singleton2 singleton;
//第三步 定义一个 getInstance
public static synchronized Singleton2 GetInstance(){
if(singleton==null){
singleton=new Singleton2();
}
return singleton;
}
}
通过测试类来进行测试
public class TestSingleton {
public static void main(String[] args) {
Singleton2 singleton = Singleton2.GetInstance();
Singleton2 singleton2 = Singleton2.GetInstance();
System.out.println(singleton.equals(singleton2));
}
}
可见实例化得到的两个对象是同一个。
优点:延迟实例化, 在需要的时候才创建对象。
缺点:线程不安全。两个线程同时使用该对象时容易出现问题。
解决办法:通过使用线程同步可以很轻松的解决。只要在定义函数时加上synchronized即可。但是又会带来另一个问题,那就是效率下降。
只有在