单例

什么是单例?
单例模式属于创建型模式,它提供了一种创建对象的最佳方式。
单例类只能有一个实例。
单例类必须自己创建自己的唯一实例。
单例类必须给所有其他对象提供这一实例。

1.饿汉式-----非线程安全
优点:类加载的时候创建一次实例,避免了多线程同步问题
缺点:即使单例没被用到也会创建,浪费内存

public class Singleton {
    private static Singleton instance = new Singleton();
    // 1.构造方法私有化,外部不能new
    private Singleton() {
    }
    //2.直接创建对象实例
    public static Singleton getInstance() {
        return instance;
    }
}

2.饿汉式----线程安全

public class SynchronizedSingleton {
    private static SynchronizedSingleton instance=new SynchronizedSingleton();
    private SynchronizedSingleton(){

    }
    public static SynchronizedSingleton getInstance(){
        return instance;
    }
}

3.懒汉式----非线程安全
优点:调用getInstance()先判断储存实例的变量是否有值,如果有直接使用,没有就创建实例将值赋给实例的变量;
缺点:没有考虑线程安全问题,多个线程并发调用getInstance,可能会创建多个实例

public class Singleton {
    //2.本类内部创建对象实例
    private static Singleton instance = null;

    // 1.构造方法私有化,外部不能new
    private Singleton() {

    }

    //3.提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

4.懒汉式----线程安全
缺点:性能问题,添加了synchronized会比一般方法慢,如果多次调用getInstance,累积的性能损耗比较大。

public class SynchronizedSingleton {
    private static SynchronizedSingleton instance = null;
    private SynchronizedSingleton() { }
    public synchronized static SynchronizedSingleton getInstance() {
        if (instance == null) {
            instance = new SynchronizedSingleton();
        }
        return instance;
    }
}

5.静态类内部加载(线程安全)
使用内部类,静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载,达到了类似懒汉模式的效果,而这种方法又是线程安全的。

public class StaticSingleton {
    private static class SingletonDepth{
        private static StaticSingleton instance=new StaticSingleton();
    }
    private StaticSingleton(){}
    public static StaticSingleton getInstance(){
        return SingletonDepth.instance;
    }
}

6.双重校验锁
有一种情况,有俩个线程,线程A执行到了第一个if条件判断instance =null,A进入了锁定块;线程B也执行到了if条件判断instance = null,但是锁被A占用,A成功实例化后退出代码块后线程B才能进入,因为A已经实例化,退出代码块。
A获取到了单例实例并返回,线程B没有获取到单例并返回Null。

public class TwinCheckSingleton {
    private static TwinCheckSingleton instance;
    private TwinCheckSingleton(){
        System.out.println("Singleton has loaded");
    }
    public static TwinCheckSingleton getInstance(){
        if(instance==null){
            synchronized (TwinCheckSingleton.class){
                if(instance==null){
                    instance=new TwinCheckSingleton();
                }
            }
        }
        return instance;
    }
}

7.枚举方法(线程安全)
创建枚举默认就是线程安全的,还能防止反序列化导致重新创建新的对象,是唯一一种不会被反射破坏单例状态的模式

public enum  EnumSingleton{
        // 定义一个枚举的元素。EnumSingleton
        INSTANCE;
        public void EnumSingletonDemo() {
            // 功能处理
            System.err.println("功能处理");
        }
}

下一篇:简单工厂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值