设计模式之单例模式

一、类与类之间的关系

1、依赖关系:在类中使用了对方

  • 是类的成员属性
  • 是类的方法参数类型
  • 是类的方法的返回值

2、泛化关系:是依赖关系的特例,其实就是继承关系

3、实现关系:是依赖关系的特例,A类实现B类或者一个类实现接口

4、关联关系:单向一对一(你中有我,我中你) 双向一对一(你中有我,我中你) 类与类之间的联系

5、聚合关系:表示整体和部分的关系 ,整体和部分可以分离(private A a;)

  • 一个类里面有一个或多个对象变量,称为单聚合或多聚合

6、组合关系:表示整体和部分的关系 ,整体和部分不可以分离( private A a=new A() )

  • 一个类里面创建new了多个类变量

二、设计模式

1.1、单例设计模式:

在整个软件系统中,对某个类只存在一个对象实例,并且该类只提供一个取得对象实例的方法(静态方法)

  • 饿汉式(静态常量)–可使用
class Singleton{
    
	// 1、构造器私有化(防止new  外部不能通过new得到对象实例)
    private Singleton(){}

    // 2、类的内部创建对象
    private final static  Singleton instance=new Singleton();

    //3、提供一个外部可访问的静态公共方法:getInstance
    public static   Singleton getInstance(){
        return instance;
    }
}

优点:简单,在类加载时就已经完成了实例化,也就是创建好了对象,避免了线程同步问题

缺点:在类加载时就已经完成了实例化,没有达到懒加载(Lazy Loading)的效果,如果该类从始至终就没有使用过,就会造成内存的浪费

  • 饿汉式(静态代码块) :优缺点同上一样
class Singleton{
    
    //1、构造器私有化(防止new  不能通过new得到对象实例)
    private Singleton(){}

    private  static  Singleton instance;

    //2、静态代码块中,创建单例对象
    static {
        instance=new Singleton();
    }

    //3、提供一个外部可访问的静态公共方法:getInstance
    public static   Singleton getInstance(){
        return instance;
    }
}
  • 懒汉式(线程不安全)
//饿汉式(静态代码块-在类被初始化的时候才会去实例化当前对象)
class Singleton{
    private  static  Singleton instance;

    private Singleton(){}

    //提供一个静态的公共方法,当使用到该类时,才去创建instance
    public static Singleton getInstance(){
        if (instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

优点:起到了懒加载(Lazy Loading)的效果,我用到就去创建,没有就不创建,避免内存浪费,但只能在单线程下使用。在多线程下,一个线程进入了if (instance==null),还未来得及往下执行,另一个线程也通过了这个if语句,这会产生多个实例,这将不是单例模式了。

  • 懒汉式(线程安全,同步方法):加入同步synchronized的代码,解决了线程安全
//饿汉式(静态代码块-在类被初始化的时候才会去实例化当前对象)
class Singleton{
    private  static  Singleton instance;

    private Singleton(){}

    //提供一个静态的公共方法,当使用到该类时,才去创建instance
    //加入同步synchronized的代码,解决了线程安全
    public static synchronized Singleton getInstance(){
        if (instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

缺点:效率低,每个线程在获取该类的实例对象时,都要执行同步,但是该方法只实例化一次就够了,后面想要获取该类实例,直接return就行。

  • 双重检查:线程安全、懒加载问题和效率问题 开发常用

    volatile:立即更新到主存 防止指令重排

class Singleton{
    private  static volatile  Singleton instance;

    private Singleton(){}

    //提供一个静态的公共方法,当使用到该类时,才去创建instance
    //加入双重检查的代码,解决了线程安全、懒加载问题和效率问题
    public static synchronized Singleton getInstance(){
        if (instance==null){
            synchronized (Singleton.class){
                if (instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}
  • 静态内部类:外部类加载时静态内部类不会被加载,如下代码所示:在调用公共静态方法时,才会调用静态内部类,这样就解决了懒加载问题,jvm在类装载时线程是安全的 开发常使用
class Singleton{

    private Singleton(){}
    
    //写一个静态内部类
    public static class SingletonInstance{
        //静态属性
        private static final Singleton INSTANCE=new Singleton();
    }
    
    //直接返回 -INSTANCE
    public static synchronized Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }
}
  • 枚举方式:推荐使用
enum  Singleton{
    INSTANCE;//属性
    public void eat(){
        System.out.println("吃");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

揽星河吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值