单例模式
1. 简述
单例模式就是保证一个类的实例在”特定范围”只有一份(例如一个 JVM 内部,一个线程内部),并且
提供一个全局访问点可以访问到这份实例。
2. 应用场景
● Spring(Singleton 作用域的 Bean 对象)
● MyBatis(ErrorContext 对象是每个线程一份此类实例)
● ......
3. 单例六种写法
● 第一种 此设计在多线程环境中存在不安全。
class Singleton01{
private Singleton01() {}
private static Singleton01 instance;
public static Singleton01 getInstance() {
if(instance==null) {
instance = new Singleton01();
}
return instance;
}
}
● 第二种 适合大对象,但是频繁访问会导致大量阻塞。
class Singleton02{
private Singleton02() {}
private static Singleton02 instance;
public static Singleton02 getInstance() {
synchronized (Singleton02.class){
if(instance==null){
instance = new Singleton02();
}
}
return instance;
}
}
● 第三种 基于singleton02优化。
class Singleton03{//基于singleton02优化
/**
* 1.尽量减少阻塞的县城
* 2.应该尽量缩小锁的应用返回(锁的代码快)
*/
private Singleton03() {}
private static volatile Singleton03 instance;
public static Singleton03 getInstance() {
if(instance==null) {//双重验证
synchronized (Singleton03.class) {
if(instance==null) {
instance = new Singleton03();
}
}
}
return instance;
}
}
● 第四种
class Singleton04{
private Singleton04() {}
private static Singleton04 instance;
public static synchronized Singleton04 getInstance() {
if(instance==null) {
instance = new Singleton04();
}
return instance;
}
}
● 第五种 适合小对象 , 频繁访问
class Singleton05{
//类加载时创建(实时加载)
private static Singleton05 instance = new Singleton05();
private Singleton05() {}
public static Singleton05 getInstance() {
return instance;
}
public static void show() {}
}
● 第六种 适合大对象 , 频繁访问
class Singleton06{
static class Inner{
private static Singleton06 instance = new Singleton06();
}
private Singleton06() {}
public static Singleton06 getInstance() {
return Inner.instance;
}
public static void show() {}
}
4. 应用分析
● 优势:科学使用资源,避免频繁创建,销毁对象时造成的资源浪费。
● 劣势:设计不够严谨会存在线程安全问题,可扩展性相对较差。