java单例模式的5种实现

来源:互联网 发布:mac 移动硬盘 win7 编辑:程序博客网 时间:2024/06/03 19:26

下面的单例实现都是线程安全的。
一、

package practise;public class Singleton1{    public static final Singleton1 INSTANCE = new Singleton1();    private Singleton1(){}}

这是比较简单的单例模式,在类加载初始化的时候就实例化INSTANCE,所以可能在没有使用INSTANCE的时候就实例化,造成资源浪费。
二、

package practise;public class Singleton2{    private static final Singleton2 INSTANCE = new Singleton2();    private Singleton2(){}    public static Singleton2 getInstance()    {        return INSTANCE;    }}

这个实现也是类加载就实例化INSTANCE,但是提供了一个静态工厂方法来获取实例,优点是提供了灵活性,以后更改getInstance的实现比较方便。

三、

package practise;public class Singleton3{    private static volatile Singleton3 INSTANCE;    private Singleton3(){}    public static Singleton3 getInstance()    {        if(INSTANCE == null)        {            synchronized (INSTANCE)            {                if(INSTANCE == null)                    INSTANCE = new Singleton3();            }        }        return INSTANCE;    }}

这个单例是延迟实例化INSTANCE,或者叫做懒汉方式,只有在第一次用到INSTANCE的时候才实例化,主要是为了节约内存。这里需要注意的是double check,双重确定INSTANCE == null,不然也可以将synchronized 放在getInstance方法上。不过绝大部分时候是不需要同步的,所以double check的效率要高很多。

四、

package practise;public class Singleton4{    private static class Inner    {        public static final Singleton4 INSTANCE = new Singleton4();    }    private Singleton4(){}    public static Singleton4 getInstance()    {        return Inner.INSTANCE;    }}

这个实现也是为了延迟实例化,并且确保线程安全,毕竟double check的实现比较麻烦。
五、

package practise;public enum Singleton5{    INSTANCE;}

这种方法在功能上与公有域方法接近,但是它更加简洁,无偿提供了序列化机制,绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候。单元素的枚举方法已经成为实现Singleton的最佳方法。——《Effective JAVA》

0 0
原创粉丝点击