解释:单例模式是为了确保在整个应用生命周期内一个类只有一个实例化对象,并且提供该实例化对象的全局访问入口
1.结构和原理
一个最基本的单例模式类包含一个私有的静态变量、一个私有的构造函数和和一个共有的静态函数。其中私有构造函数保证了该类不能通过构造函数来实例化,只能通过共有的静态函数返回一个唯一的私有静态变量。
2.实现单例模式
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
注意:懒汉模式在多线程环境中是不安全的,例如当前有n个线程同时执行 getInstance() 方法时,此时的instance都为null,那么Singleton类就会被实例化n次。这与单例模式的设计初衷相悖。
public class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
备注:在懒汉模式中,线程不安全是由于instance被多次实例化所造成的,在饿汉模式中直接实例化Singleton就解决了线程不安全问题。但是这种方式就失去了延迟实例化的好处。
public class Singleton{
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
说明:volatile关键字的作用是在多线程环境下,禁止JVM的指令重排列
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){
return SingletonProvider.INSTANCE;
}
public static class SingletonProvider{
private static final Singleton INSTANCE = new Singleton();
}
}
静态内部类模式与饿汉模式有异曲同工之处
public enum Singleton{
INSTANCE;
private String name;
//getter()...
// setter()...
// otherMethod()...
}
public class UserEnumSingleton{
Singleton instance = Singleton.INSTANCE;
instance.setName("example");
System.out.println(instance.getName());
Singleton instance2 = Singleton.INSTANCE;
instance2.setName("example2");
System.out.println(instance2.getName());
instance.otherMethod();
//other options...
//使用java反射原理操作
try{
Singleton[] enums = Singleton.class.getEnumConstants();
for(Singleton instance : enums){
System.out.println(instance.getName());
}
}catch(Exception e){
e.printStackTrace();
}
}
example
example2
example2
3.总结
优点
单例模式使得应用系统中一个类只被实例化一次,节省系统资源开销,对于系统中需要频繁创建和销毁的对象,使用单例模式可以在一定程度上提高系统的性能。
缺点
由于采用单例模式对类进行设计,就必须要记住获取对象的入口,即共有的静态函数名,而不是采用new关键字进行类的实例化,这在多人协同开发的项目中会给开发人员带来一些困扰(看不到源码),因此需要统一编码规范。
适用的范围
留言与评论(共有 0 条评论) |