Java的单例模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的单例模式相关的知识,希望对你有一定的参考价值。

一:什么是Java单例模式?
单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,
有时候我们只需要某个类同时保留一个对象,不希望有更多的对象。适于使用java单例模式。
二:单例模式的特点:
1.单例模式只能有一个实例
2.单例类必须创建自己的一个唯一实例
3.单例类必须向其他类提供这个实例。

其实,就是要保证对象的唯一性。
三:那么如何保证对象的唯一性呢?需要三步就可以保证对象的唯一性。

(1)不允许其他程序用new对象。

? ? 因为new就是开辟新的空间,在这里更改数据只是更改的所创建的对象的数据,如果可以new的话,每一次new都产生一个对象,这样肯定保证不了对象的唯一性。

(2)在该类中创建对象
? ?因为不允许其他程序new对象,所以这里的对象需要在本类中new出来

(3)对外提供一个可以让其他程序获取该对象的方法

? ?因为对象是在本类中创建的,所以需要提供一个方法让其它的类获取这个对象。

那么这三步怎么用代码实现呢?将上述三步转换成代码描述是这样的
(1)私有化该类的构造函数
(2)通过new在本类中创建一个本类对象
(3)定义一个公有的方法,将在该类中所创建的对象返回
三:懒汉模式(即懒加载)
1.在调用 getInstance()的时候才去创建对象

public class Singleton {

    private static Singleton instance=null;

    private Singleton() {};

    public static Singleton getInstance(){

        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }

上面的代码是线程不安全的,可能存在这种情况:A线程还未来得及实例化该Singleton对象,B线程也进入了if语句所以它也会实例化Singleton对象。

2.懒汉模式的线程安全写法:加锁
public class Singleton {

    private static Singleton instance=null;

    private Singleton() {};

    public static synchronized Singleton getInstance(){//给方法加锁

        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

上面的代码效率很低。
3.双重加锁机制保证线程安全。


    public class Singleton {

private static  volatile Singleton instance=null;

private Singleton() {};

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

即满足懒加载又满足线程安全性。

四:饿汉模式(一开始就创建了对象)
1.

public class Singleton {

    private static Singleton instance=new Singleton();
    private Singleton(){};
    public static Singleton getInstance(){
        return instance;
    }
}

2. 使用静态代码块实例化该对象(在调用方法之前就实例了该对象)

public class Singleton{

private static Singleton instance = null;

static {
    instance = new Singleton();
}

private Singleton() {};

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

五:内部类(也是延迟加载)

public class Singleton{

    private Singleton() {};

    private static class SingletonHolder{
        private static Singleton instance=new Singleton();
    } 

    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

静态内部类方式在Singleton类被装载时没有立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonHolder类,从而完成Singleton的实例化。

以上是关于Java的单例模式的主要内容,如果未能解决你的问题,请参考以下文章

Java中的单例模式

你真的会写JAVA的单例模式吗?

性能比较好的单例写法

java的单例模式,为什么需要volatile

怎么实现一个线程安全的单例模式

ABAP和Java里的单例模式攻击