单例

1、简介

单例较简单,分为饿汉式(加载类时创建)、懒汉式(使用时创建)、双检索(为线程安全)

2、场景

例如:

  1. 工厂(SqlSessionFactoryBean、)
  2. 上下文(ApplicationContext、ServletContext、SecurityContext、...)
  3. 系统环境信息(ProcessEnvironment)
  4. 连接池()
    等、、、

3、举例

1.1 饿汉式

饿汉式主要是在初始化类时创建不可变静态对象,这样在程序启动后,无论多少次通过getInstance获取【构造器私有,不能通过new创建】Person类,都只能拿到同一个对象。
创建Person类

public class Person {
    private String name;
    private String age;
    //初始化时创建对象
    private static final Person instance = new Person();

    /**
     * 私有构造器
     */
    private Person(){}

    /**
     * 获取单例对象
     * @return
     */
    public static Person getInstance(){
        return instance;
    }

}

测试

public class MainTest {
    public static void main(String[] args) {
        Person instance1 = Person.getInstance();
        Person instance2 = Person.getInstance();
        System.out.println(instance1 == instance2);
    }
}

1.2 懒汉式

懒汉式主要在通过getInstance方法获取对象时做判断。如果没有,创建对象,赋值属性,返回属性。如果对象不为空,返回已存在的对象。
创建Anima类

public class Animal {
    private String name;
    private String age;

    private static Animal instance;

    private Animal(){}

    public static Animal getInstance(){
        //为空时创建对象,放在属性上
        if(instance == null){
            instance = new Animal();
        }
        return instance;
    }
}

测试

public class MainTest {
    public static void main(String[] args) {

        Animal instance3 = Animal.getInstance();
        Animal instance4 = Animal.getInstance();
        System.out.println(instance3 == instance4);

    }
}

1.3 双检索+内存可见性

-- 双检索单例主要是为了保证线程安全的同时,使锁住的代码块足够小,以增加效率。
-- 因为创建对象过程中线程不安全,需要对instance属性加volatile使instance属性内存可见
创建Clothes类

public class Clothes {
    private String color;
    private String type;

    private volatile static Clothes instance;

    private Clothes(){};

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

测试

public class MainTest {
    public static void main(String[] args) {

        Clothes clothes1 = Clothes.getInstance();
        Clothes clothes2 = Clothes.getInstance();
        System.out.println(clothes1 == clothes2);
    }
}

end...

你可能感兴趣的:(单例)