1. 什么是单例模式?
单例模式:就是在我们的应用程序中某个类值存在一个实例。
1. 懒汉式:要用的时候才进行实例化(懒人有拖延症)
1. 私有化构造方法;
2. 声明一个私有化静态的当前对象变量,不进行实例化;
3. 提供加同步锁的公开的静态方法,用于获取当前对象,当对象为null时创建,不为null时直接返回;
缺点:在并发的情况下,多个线程访问这个对象时候,因为他是同步的,需要等待,影响性能;
public class Student {
private Student(){}
private static Student student = null;
public static synchronized Student getInstance(){
if(student == null){
student = new Student();
}
return student;
}
}
2. 饿汉式:
1. 私有化构造方法
2. 声明一个私有化静态的当前对象,需要进行实例化
3. 提供公开的静态方法,用于获取当前对象,
缺点:一次性创建好了,无法往单例对象的构造方法传参,不能起到延迟加载的效果,而且占据内存;
public class Student {
private Student(){}
private static Student student = new Student();
public static Student getInstance(){
return student;
}
}
3. 双重判断:推荐使用
volatile private static entity = null;
public static entity getInstance(){
if(entity == null){
synchronized(entity.class){
if(entity == null){
entity = new entity();
}
}
}
return entity;
}
synchronized(entity.class) 在这个类上加入同步锁,这个类中当前方法都不能被其他线程调用;
volatile:当多个线程访问同一个变量是,如果其中一个线程改变了这个变量的值,
其他线程能被及时通知到这个变量已经发生 改 变了;
他会屏蔽掉虚拟机的一些代码优化,一般不适用;
4. enum:枚举
枚举的构造方法默认是私有的
通过枚举实现单例模式;简洁,自由序列化,又不存在多线程的问题;一般在java源码中见到此用法;
public enum EnumStudent {
红色"),white(2,"白色");
private int key;
private String value;
EnumStudent(int key,String value){
this.key = key;
this.value = value;
}
public int getKey() {
return key;
}
public String getValue() {
return value;
}
}
5. 静态内部类实现单例模式:
既能够做到延时加载,又能够实现线程安全;
静态属性,静态代码块在类加载的时候就分配空间了,而静态类在调用的时候才去加载;
public class Singleton{
private Singleton(){}
private static class SingletonHolder{
//静态内部类的静态属性的实例化,由JVM保证线程的安全
private static Singleton instance = new Singleton();
}
public static Singleton getInstance(){
只有调用getInstance方法时,才回去实例化instance属性
return SingletonHolder.instance;
}
}