设计模式-1-单例模式

1.单例模式是什么?

定义:
保证一个类中在任何情况下只有一个实例
并且提供一个全局访问点。

单例模式主要特点:
1、构造方法私有化;
2、实例化的变量引用私有化;
3、获取实例的方法共有。

2.单例模式有哪些?

1.饿汉式(静态常量)


public class HungrySingleton1 {
    //1.私有创建实例化对象
    private static final HungrySingleton1 instance = new HungrySingleton1();
    //2.私有化构造
    private  HungrySingleton1(){

    }
    //3.提供公共静态访问方法,返回实例对象
    public static HungrySingleton1 getInstance(){
        return instance;
    }
}

优点:
类加载的时候实例化,避免了线程同步问题
缺点:
如果从头到尾没有使用过实例,会造成内存浪费
结论
可以使用,但可能会浪费资源

2.饿汉式(静态代码块)

public class HungrySingleton2 {
    //1.创建对象实例
    private static HungrySingleton2 instance;

    //2.私有化构造器
    private HungrySingleton2(){}

    //3.静态代码块中创建对象
    static {
        instance=new HungrySingleton2();
    }

    //3.提供公共静态访问方法,返回对象实例
    public static HungrySingleton2 getInstance(){
        return instance;
    }
}

结论:
区别是在静态代码块中创建实例对象,优点和缺点同上,可能浪费内存资源。

3.懒汉式(线程不安全)

public class LazySingleton1 {
    //1.声明私有变量
    private static LazySingleton1 instance;

    //2.私有构造
    private LazySingleton1(){}

    //3.提供公共静态方法,使用时才创建对象
    public static LazySingleton1 getInstance(){
        if (instance == null){
            return instance = new LazySingleton1();
        }
       return instance;
    }
}

优点:
有懒加载的作用,但只能在单线程中使用
缺点:
多线程中,一个线程进入if语块,还没有来得及往下执行,
另一个线程通过了if语句,会产生多个实例,违反了一个类中保证只有一个实例的原则,多线程中不可以使用
结论:
实际开发中中不推荐使用

4.懒汉式(线程安全,同步方法)

public class LazySingleton2 {
    private static LazySingleton2 instance;

    //2.私有构造
    private LazySingleton2(){}

    //3.提供公共静态方法,使用时才创建对象
    // 加了同步关键字,解决了线程安全问题
    public static synchronized LazySingleton2 getInstance(){
        if (instance == null){
            return instance = new LazySingleton2();
        }
        return instance;
    }
}

优点:
懒加载,解决了线程安全问题
缺点:
每个线程想获得实例的时候,都要执行同步方法,方法同步效率低
结论
实际开发中不推荐这种方式

5.懒汉式(线程安全,同步代码块)

public class LazySingleton3 {
    //1.声明私有化静态变量
    private static LazySingleton3 instance;

    //2.私有构造
    private LazySingleton3(){}

    //3.提供公共静态方法,使用时才创建对象
    // 加了同步代码块,解决了线程安全问题
    public static LazySingleton3 getInstance() {
        if (instance == null) {
            synchronized (LazySingleton3.class) {
                return instance = new LazySingleton3();
            }
        }
        return instance;
    }
}

结论:
不推荐使用

**

6.双重检查方式

**

public class DoubleCheckSingleton {
    //1.声明私有静态同步变量
    private static volatile DoubleCheckSingleton instance;

    //2.私有化构造
    private DoubleCheckSingleton(){}

    //3.提供公共静态方法,懒加载
    //加入双重检查代码,解决线程安全
    public static synchronized DoubleCheckSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

优点:
1.多线程开发中经常使用,使用了两次if判断,保证了线程的安全。
2.实例化代码只用执行一次,后面再次访问,
判断if(instance==null)直接return实例,
避免反复进行方法同步。
3.延迟加载,效率较高
结论:
实际开发中推荐使用这种方式。

7.静态内部类方式

public class StaticClassSingleton {
    //1.声明静态同步变量
    private static volatile StaticClassSingleton instance;

    //2.私有化构造
    private StaticClassSingleton(){}

    //3.定义静态内部类中静态属性
    private static class SingletonInstance{
        private static final StaticClassSingleton INSTANCE = new StaticClassSingleton();
    }

    //4.提供一个公共静态方法
    public static synchronized StaticClassSingleton getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

优缺点:
1.使用类装载机制保证初始化实例时只有一个线程
2.静态内部类在类装载时不会立即实例化,
需要的时候才调用方法,装载静态内部类,完成实例化。
3.类的静态属性只有在类第一次加载时初始化,JVM帮助保证了线程的安全性,类初始化时,别的线程无法进入。
结论:
线程安全,延迟加载,效率高,推荐使用

8.枚举方式

public enum  EnumSingleton {
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}

优缺点:
1.可以避免多线程同步问题,避免反射攻击,防止反序列化重新创建新的对象。
结论:
推荐使用

3.单例模使用注意事项

1.单例模式保证了内存中一个类只存在一个对象,节省了系统资源,
对于一些频繁创建销毁的的对象,可以使用单例模式。

2.当要实例化一个类的时候,可以使用获取对象的方法,而不是new出来。

3.单例模式的使用场景:工具类,数据库源,session工厂等。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值