01什么是Java单例模式
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。选择单例模式就是为了避免不一致状态,避免出现多个实例对象。
02单例模式特点
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式保证了全局对象的唯一性,比如系统启动读取配置文件就需要单例保证配置的一致性。
单例模式
01饿汉单例模式【静态常量】
采用的方式是立即加载的方式
public class Singleton{
//私有构造
private Singleton(){}
private static single = new Singleton();
//静态工厂方法
public static Singleton getInstance(){
return single;
}
}
这种写法比较简单,就是在类装载的时候就完成实例化,避免了线程同步问题。
饿汉模式的特点是在类中创建静态属性的时候就赋值并且只执行一次也就是说只创建一次对象使用时直接用类名调用静态对象达到创建一个对象的目的
Singleton ss = Singleton.single;
02恶汉单例模式【静态代码】
public class Singleton {
private static Singleton instance;
static {
instance = new Singleton();
}
private Singleton() {}
public Singleton getInstance() {
return instance;
}
}
懒汉式 在多线程环境中会发生线程安全问题 (可以解决线程问题)
饿汉式不管是在单线程还是在多线程中 不存在线程安全问题 建议定义单例模式的话 用饿汉式
饿汉式单例模式要比懒汉式效率高
03懒汉单例模式【线程不安全】
延迟加载的方式处理对象的产生
public class Singleton{
//私有构造
` private Singleton(){};
private static Singleton single = null;
public static Singleton getInstance(){
if(single==null){
single = new Singleton();
}
return single;
}
}
此时会存在一个问题若是存在多线程情况下此时会产生多个对象使用synchronized同步锁解决问题
04懒汉单例模式【线程安全,同步锁处理】
public class Singleton {
// 私有构造
private Singleton() {}
private static Singleton3 single = null;
public static Singleton3 getInstance() {
// 等同于 synchronized public static Singleton3 getInstance()
synchronized(Singleton.class){
// 注意:里面的判断是一定要加的,否则出现线程安全问题
if(single == null){
single = new Singleton();
}
}
return single;
}
}
在方法上加synchronized同步锁或是用同步代码块对类加同步锁,此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。
05懒汉单例模式【线程安全,双重检查】
public class Singleton4 {
// 私有构造
private Singleton4() {}
private static Singleton4 single = null;
// 双重检查
public static Singleton4 getInstance() {
if (single == null) {
synchronized (Singleton4.class) {
if (single == null) {
single = new Singleton4();
}
}
}
return single;
}
}
06懒汉单例模式【线程安全,同步代码块】
public class Singleton {
private static Singleton singleton;
private Singleton() {}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
singleton = new Singleton();
}
}
return singleton;
}
}