2

一、饿汉式

1.示例代码

public class HungrySingleClass {

    private static HungrySingleClass hungrySingleClass = new HungrySingleClass();

    private HungrySingleClass() {

    }

    /**
     * 单例方法
     * @return
     */
    public static HungrySingleClass getInstance() {
        return hungrySingleClass;
    }
}

2.代码理解

  • 先创建一个私有的构造函数(防止其它地方直接实例化),创建私有变量防止其他人访问
  • 为什么要使用static关键字?由于构造器被私有,没办法创建类再访问getInstance方法,因此只能从类一级,即HungrySingleClass.getInstance()。由于静态方法只能访问静态变量,因此变量也需要使用static修饰

二、懒汉式

1.示例代码

public class LazySingleClass {
    private volatile static LazySingleClass lazySingleClass = null;

    private LazySingleClass() {

    }

    public static LazySingleClass getInstance() {
        if(lazySingleClass == null) {
            synchronized (LazySingleClass.class) {
                if(lazySingleClass == null) {
                    lazySingleClass = new LazySingleClass();
                }
            }
        }
        return lazySingleClass;

    }
}

2.代码理解

  • 懒汉式只有当单例为空的时候才回去实例化单例的值
  • 线程安全:由于懒汉式符合多个线程同时修改同一个变量,因此我们需要synchronized
  • 优化:由于每次都需要去拿锁浪费效率,因此加入双重校验锁,在synchronized前面多添加一个if判断
  • volatile关键字的作用:禁止指令初始化。实例化对象步骤为:为对象分配内存、初始化对象、将内存地址赋值给 instance 变量。指令初始化会导致步骤2、3颠倒。假设线程A正在实例化对象,当他进行实例化对象时,虽然内存地址赋值给了instance对象,但是并没有初始化,此时线程B进行第一个if条件判断,返回了一个并未完全初始化的对象。volatile关键字保证要么instance是null,要么是一个完整的对象

原来是小袁呐
1 声望0 粉丝