单例模式
定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
类型:创建类模式
类图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0TSHtbll-1576640726128)(C:\Users\zsj55\AppData\Roaming\Typora\typora-user-images\1568448059405.png)]
单例模式有以下要点:
- 具有私有构造方法
- 指向自己实例的私有静态引用
- 以自己实例为返回值的静态的公有方法
单例模式根据实例化对象时机的不同分为两种:一种是懒汉式单例,另一种式饿汉式单例。饿汉式单例在单例类被加载时,就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象。
代码如下:
饿汉式单例
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getSingleton(){
return singleton;
}
}
懒汉式单例
线程安全,延迟初始化。这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
双重检查模式,进行了两次的判断,第一次是为了避免不要的实例,第二次是为了进行同步,避免多线程问题。由于singleton=new Singleton()对象的创建在JVM中可能会进行重排序,在多线程访问下存在风险,使用volatile修饰signleton实例变量有效,解决该问题。
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class){
if(uniqueInstance == null){//进入区域后,再检查一次,如果仍是null,才创建实例
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
用枚举实现的线程安全的单例模式
public enum SerEnumSingleton implements Serializable {
INSTANCE;
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
private SerEnumSingleton() {
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
SerEnumSingleton s = SerEnumSingleton.INSTANCE;
s.setContent("枚举单例序列化");
System.out.println("枚举序列化前读取其中的内容:"+s.getContent());
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("SerEnumSingleton.obj"));
oos.writeObject(s);
oos.flush();
oos.close();
FileInputStream fis = new FileInputStream("SerEnumSingleton.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
SerEnumSingleton s1 = (SerEnumSingleton)ois.readObject();
ois.close();
System.out.println(s+"\n"+s1);
System.out.println("枚举序列化后读取其中的内容:"+s1.getContent());
System.out.println("枚举序列化前后两个是否同一个:"+(s==s1));
}
}
+s1.getContent());
System.out.println(“枚举序列化前后两个是否同一个:”+(s==s1));
}
}