码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2020-06-19 11:47:21      阅读:40      评论:0      收藏:0      [点我收藏+]

标签:序列   构造器   pre   instance   jvm   win   for   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-基础知识-设计模式-单例模式

标签:序列   构造器   pre   instance   jvm   win   for   java   基础   

原文地址:https://www.cnblogs.com/zxj-study/p/13161933.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!