java-基础知识-设计模式-单例模式

Posted zxj-study

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java-基础知识-设计模式-单例模式相关的知识,希望对你有一定的参考价值。

1.饿汉式

类加载到内存后,就实例化一个单例,jvm保证线程安全  推荐使用
缺点:不管用到与否,类加载时就会完成实例化  (类加载static修饰的就会执行)
额外知识点(一般对象)
//使用反射的方式   也叫做通过反序列化的方式获取对象
Class clazz=Class.forName("")  //这时候只会类加载把class放入内存
clazz.newInstance();   //这时候才实例化
//一般创建对象
new Object()   //使用构造器创建对象,类加载并实例化
public class Singleton1 {
    private static final Singleton1 singleton1=new Singleton1();
    private  Singleton1() {}

    public Singleton1 getInstance(){
        return singleton1;
    }
}

2.懒汉式


优化了饿汉式,达到了按需初始化的目的。但是多线程时会带来线程不安全问题
public class Singleton2 {
    private static Singleton2 singleton2;
    private Singleton2() {
    }
    public Singleton2 getInstance(){
        if(singleton2==null){
            singleton2=new Singleton2();
        }
        return singleton2;
    }

线程1获取对象时,当执行到if语句时,判断对象为空,但是还没有执行构造器,这时候线程2也执行if语句。线程1与线程2都执行了构造器,所以获取到的对象不是同一个,即不是单例

3.懒汉式(线程安全版

public class Singleton3 {
    private static volatile Singleton3 singleton3;
    private Singleton3() {
    }
    public Singleton3 getInstance(){
        if(singleton3==null){
            synchronized(this){
                if(singleton3==null) {
                    singleton3 = new Singleton3();
                }
            }
        }
        return singleton3;
    }
}

第一个if的作用是  节省代码执行的时间

第二个if的作用  保证此线程操作时其他线程没有改变其值,保证其原子性

volatile的作用  java虚拟机内部执行的时候对于Java汇编语言进行优化,语句重排。 如果不加, 没有初始化的时候就返回singleton3,导致无法单例。

4.枚举的方式

目前最完美的写法,不仅可以解决线程同步,而且还能防止反序列化。  但是不太推荐使用

public enum Singleton4 {
    INSTANCE;
}

 

以上是关于java-基础知识-设计模式-单例模式的主要内容,如果未能解决你的问题,请参考以下文章

JAVA知识总结:单例模式和多态

java基础-单例设计模式

java基础-单例设计模式

java基础之----23种设计模式(单例模式)

Java基础-单列设计模式

JAVA基础-常用的设计模式