学习JAVA.day12 设计模式(单例模式)

学习JAVA.day12 设计模式(单例模式)

因为在设计或开发中,肯定会有这么一种情况,一个类只能有一个对象被创建,如果有多个对象的话,可能会导致状态的混乱和不一致。这种情况下,单例模式是最恰当的解决办法。它有很多种实现方式,各自的特性不相同,使用的情形也不相同。今天要实现的是常用的三种,分别是饿汉式、懒汉式和多线程式。
单例的四大原则:

  1. 构造私有。
  2. 以静态方法或者枚举返回实例。
  3. 确保实例只有一个,尤其是多线程环境。
  4. 确保反序列换时不会重新构建对象。

通过单例模式,可以做到:

  1. 单例类只能有一个实例。
  2. 单例类必须自己创建自己的唯一实例。
  3. 单例类必须给所有其他对象提供这一实例。

1). 饿汉式
饿汉单例,即在最开始的时候,静态对象就已经创建完成;
设计方法是类中包含一个静态成员指针,该指针指向该类的一个对象,提供一个公有的静态成员方法,返回该对象指针;为了使得对象唯一,还需要将构造函数设为私有;
代码实现:

package cn.itcast.day23;

public class Single {    //饿汉式
    private Single() {}
    private static final Single singleNode = new Single();
    //静态工厂方法:
    //静态工厂方法指的是在类中提供一个公有的静态方法,返回类的一个实例。
    public static Single getInstance() {
        return singleNode;
    }
}

线程安全问题:单例的饿汉实现是线程安全的,因为对象在使用前就已经创建出来了。
2). 懒汉式
所谓懒汉模式,就是尽可能晚的创建这个对象的实例,即在单例类第一次被引用时将自己初始化;其实JAVA里很多地方都是类似这样的思想,目的是尽量使资源的利用最大化,不要让空闲的人还占着有限的资源。
代码实现:

package cn.itcast.day23;

public class  Single{    //懒汉式
    private Single() {}
    private static Single singleNode = null;
    public static Single getInstance() {
        if (singleNode == null) {
            singleNode = new Single();
        }
        return singleNode;
    }
}

线程安全问题:如果此时多线程进行操作,简单点以两个线程为例,假设pthread_1刚判断完 singleNode 为null为真,准备创建实例的时候,切换到了pthread_2, 此时pthread_2也判断singleNode 为null为真,创建了一个实例,再切回pthread_1的时候继续创建一个实例返回,那么此时就不再满足单例模式的要求了。
解决方法:
(1). 在getInstance方法上加同步

package cn.itcast.day23;

public class  Single{    //懒汉加同步
    private Single() {}
    private static Single singleNode = null;
    public static synchronized Single getInstance() {
        if (singleNode == null) {
            singleNode = new Single();
        }
        return singleNode;
    }
}

(2). 双重检查锁定

package cn.itcast.day23;

public class  Single{    //懒汉加同步
    private Single() {}
    private static Single singleNode = null;
    public static Single getInstance() {
        if (singleNode == null) {
            synchronized (Single.class) {
                if (singleNode == null) {
                    singleNode = new Single();
                }
            }
        }
        return singleNode;
    }
}

有关“双重检查锁定失效”的说明: http://ifeve.com/doublecheckedlocking/

(3). 静态内部类

package cn.itcast.day23;

public class Single {
    private static class Inner {
        private static final Single singleNode = new Single();
    }
    private Single (){}
    public static final Single getInstance() {
        return Inner.singleNode;
    }
}

深入理解单例模式:静态内部类单例原理: https://blog.csdn.net/mnb65482/article/details/80458571

别问,问就是不会,需要继续深造;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值