java设计模式(单例模式)

设计模式之单例模式

一.什么是单例模式

​ 确保类只有一个实例,不会出现多个

二.单例模式解决了什么问题

​ 保证类在内存的对象唯一

三.单例模式的两种形式

饿汉式

public class Single{

    private static  Single instance = new Single();

    private Single(){

    }

    public static Single getInstance(){

        return instance;

    }

}

1.为什么叫这种模式为饿汉式?

​ 类在加载的时候就创建好了这个对象

2.为什么构造方法是私有的,方法是静态的,属性也是静态的?

​ 首先单例模式只创建一个实例,是不能通过new去创建实例的,所以构造方法是私有的

​ 第二不能通过实例去调用方法,只能通过类名去访问,所以方法是静态的 由于静态方法只能访

  问静态的属性所以属性也是静态的。 

  1. 恶汉式线程安全的,由于类加载是按需加载,且只加载一次,上述单利模式中,在类加载的时候就已经创建好了对象,并且在在整个声明周期中只创建一次

懒汉式线程不安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Single{

private static Single single = null;

public Single{

}

public static Single getInstance(){

if(single == null){
single = new Single();
}

return single;
}
}
线程安全
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Single{

private volatile static Single single = null;

public static Single getInstance(){

if(single == null){ //如果single已经实例化,则不在去获取锁,提高效率
synchronized(Single.class){
if(single == null){
single = new Single();
}
}
}

return single;
}
}

注意: volatile 关键是一定要加的

原因:single = new Single(); 操作不是原子性的,它分为三步

1. 分配内存空间
   2. 初始化对象
   3. 将初始化化的对象赋值给single

如果不加volatile,它可能会进行指令重排,执行步骤可能变为:

  1. 分配内存空间
  2. 将初始化的对象赋值给single
  3. 初始化对象

假设两个线程,线程一和线程二都执行到synchronized代码块那一行,这时候线程一先抢到锁,进入同步代码块中,执行 single = new Single(),在single = new Single()还未执行完成时,也就是执行了指令重排后的第二步,这时候single不为空了,线程二开始执行,返回single,这个single是不完整的

文章目录
  1. 1. 设计模式之单例模式
    1. 1.1. 一.什么是单例模式
    2. 1.2. 二.单例模式解决了什么问题
    3. 1.3. 三.单例模式的两种形式
      1. 1.3.1. 饿汉式
      2. 1.3.2. 懒汉式线程不安全
        1. 1.3.2.1. 线程安全
|
载入天数...载入时分秒...