设计模式 (Design pattern) 提供了在软件开发过程中面临的 一系列 问题的最佳解决方案,是 Java 开发者必修的一门课程。次要分 创立型模式、结构型模式和行为型模式 。 单例模式 是 Java 中最简略的设计模式之一,属于 创立型模式。
单例模式
单例模式从字面的角度来讲 繁多实例 / 一个对象 的 模式 .
那么首先咱们须要思考的是谁去创立这个对象, 或者说拿什么去创立这个对象.
创建对象的时候咱们都须要调用咱们类中的构造方法, 那么谁都能够调用咱们的构造方法, 咱们就没方法使其有且只有一个对象, 那么如何能力让一个类有且只有一个对象呢.
咱们须要将 构造方法私有化 , 并且在 类中本人去创立这个惟一的实例 , 而后提供一个 能够被内部拜访的办法 .
单例模式中最罕用的两种:饿汉式, 懒汉式
一、饿汉式
顾名思义: 饿, 狼吞虎咽, 只有有, 我就吃.
就是指当类被加载的时候就会创建对象.
/**
* Author:Lss
* Date: 2020-09-27 11:16
* Description: 饿汉式单例模式
* 长处: 类加载时实现初始化, 并且没有桎梏, 进步执行效率.
* 毛病: 类加载的时候就初始化, 不论用与不必都占用内存空间, 节约了内存, 且加载速度慢.
*/
public class HungryPattern {
// 通过 private 封装创立好的对象 -- 公有属性对外界不可见
private static final HungryPattern hungryPattern = new HungryPattern();
// 创建对象的时候都会调用咱们的构造方法
// 私有化构造方法 -- 目标就是为了管制外界创建对象的权限
private HungryPattern() {System.out.println("HungryPattern 对象被创立了!");
}
/**
* 既然公有的结构形式, 没有方法 new 对象了, 也就没方法通过 援用. 办法 的形式来调用,
* 那么还想调用就必须将其申明为 static 动态的, 这样就能够通过类名. 调用,
* 而且什么中央都能够拜访就必须将访问控制修饰符设置为 public
*/
public static HungryPattern getInstance(){return hungryPattern;}
}
一、懒汉式
顾名思义: 懒, 不会提前做筹备工作, 只有逼到份儿上, 才会做.
就是指当第一次被应用的时候才会创建对象.
1. 懒汉式单例模式(线程不平安)
/**
* Author:Lss
* Date: 2020-09-27 11:18
* Description: 懒汉式单例模式(线程不平安)
* 长处: 第一次调用才创建对象,防止内存节约。* 毛病: 多线程不平安, 因为没有加锁 synchronized, 不能保障单例
* 不举荐应用
*/
public class LazyPattern {// 封装创立好的对象 -- 先不创建对象,啥时候用啥时候创立(懒)
private static LazyPattern lazyPattern = null;
// 私有化构造方法 -- 目标就是为了管制外界创建对象的权限
private LazyPattern(){System.out.println("LazyPattern 对象被创立了!");
}
// 提供了公开的获取对象的办法
public static LazyPattern getInstance(){if (lazyPattern == null){lazyPattern = new LazyPattern();
}
return lazyPattern;// 提早加载
}
}
2. 懒汉式单例模式(线程平安)
/**
* Author:Lss
* Date: 2020-09-27 11:23
* Description: 懒汉式单例模式(线程平安 - 锁办法)
* 长处: 第一次调用才创建对象,防止内存节约。* 毛病: 加锁 synchronized 保障了单例, 然而锁的范畴太大, 影响效率
* 不举荐应用
*/
public class LazyPattern {// 封装创立好的对象 -- 先不创建对象,啥时候用啥时候创立(懒)
private static LazyPattern lazyPattern = null;
// 私有化构造方法 -- 目标就是为了管制外界创建对象的权限
private LazyPattern(){System.out.println("LazyPattern 对象被创立了!");
}
// 提供了公开的获取对象的办法
public static synchronized LazyPattern getInstance(){if (lazyPattern == null){lazyPattern = new LazyPattern();
}
return lazyPattern;// 提早加载
}
}
3. 懒汉式单例模式(线程平安 — 双重校验)
双重校验: 咱们又称双检锁 / 双重校验锁(DCL,即 double-checked locking)
/**
* Author:Lss
* Date: 2020-09-27 11:28
* Description: 懒汉式单例模式(线程平安 - 双重查看)
* 长处: 双重查看在多线程平安的状况下, 减小了锁的范畴, 即保障了平安的状况下也放弃了高性能
* 举荐应用
*/
public class LazyPattern {// 封装创立好的对象 -- 先不创建对象,啥时候用啥时候创立(懒)
private static LazyPattern lazyPattern = null;
// 私有化构造方法 -- 目标就是为了管制外界创建对象的权限
private LazyPattern(){System.out.println("LazyPattern 对象被创立了!");
}
// 提供了公开的获取对象的办法
public static LazyPattern getInstance(){
// 先查看实例是否存在,如果不存在才进入上面的同步块
if (lazyPattern == null){
// 同步块
synchronized(LazyPattern.class){
// 再次查看实例是否存在,如果不存在才创立实例
if (lazyPattern == null){lazyPattern = new LazyPattern();
}
}
}
return lazyPattern;// 提早加载
}
}
4. 懒汉式单例模式(线程平安 — 动态外部类实现)
/**
* Author:Lss
* Date: 2020-09-27 11:39
* Description: 懒汉式单例模式(线程平安 - 动态外部类实现)
* 举荐应用
*/
public class LazyPattern {
// 私有化构造方法 -- 目标就是为了管制外界创建对象的权限
private LazyPattern(){System.out.println("LazyPattern 对象被创立了!");
}
private static class InnnerSingleton{private static final LazyPattern LAZY_PATTERN = new lazyPattern();
}
// 提供了公开的获取对象的办法
public static LazyPattern getInstance(){return InnnerSingleton.LAZY_PATTERN;// 提早加载}
}