JAVA设计模式之单例模式

一.简介

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例.

二.实现

依次介绍和实现几种单例实现的方法.

1.懒汉-方法1

public class Singleton {
    private Singleton() {
    }

    private static Singleton instance = null;

    public static Singleton getInstance() {
        if (instance == null) {// 1
            instance = new Singleton();
        }
        return instance;
    }
}
    PS:具有lazy loading的效果.但却是线程不安全,可能会发现在两个线程重试进入"//1"处的判断,创建两个实例对象

2.懒汉-方法2

public class Singleton {
    private Singleton() {
    }

    private static Singleton instance = null;

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

3.懒汉-方法3(懒汉-方法2的另种写法)

public class Singleton {
    private Singleton() {
    }

    private static Singleton instance = null;

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

4.饿汉-方法1

这种方式基于classloder机制避免了多线程的同步的问题,不过,instance在类装载时就实例化,显然没有达到lazy loading(延迟装载)的效果。
public class Singleton {
    private Singleton() {
    }

    private static Singleton instance = new Singleton();

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

5.饿汉-方法2

这种方式同上,类装载时就会实例化,没有达到lazy loading(延迟装载)的效果。
public class Singleton {
    private Singleton() {
    }

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

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

6.双重校验锁

因为多线程同时到"instance==null"的概率是非常低,所以为了避免加锁所带来的性能问题,大神们久设计的下面的结构,即为:双重校验锁
public class Singleton {
    private Singleton() {}
    private static Singleton instance = null;
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

7.内部静态类(推荐)

public class Singleton {
    private Singleton() {
    }

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

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

8.枚举(推荐)

//类Resource是我们要应用单例模式的资源
class Resource{
}
//SomeThing.INSTANCE.getInstance() 即可获得所要实例
public enum ResourceInstance {
    INSTANCE;
    private Resource instance;
    ResourceInstance() {
        instance = new Resource();
    }
    public Resource getInstance() {
        return instance;
    }
}

PS:在枚举中我们定义构造方法限制为私有,在我们访问枚举实例时会执行一次构造方法,同时每个枚举实例都是static final类型的,也就表明只能被实例化一次。在调用构造方法时,我们的单例被实例化。也就是说,因为enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也被保证实例化一次。可以看到,枚举实现单例还是比较简单的。

三.各种单例写法之间的对比

在使用单例的时候基本上我们关注的基本上就是:是否线程安全,是否具有lazy loading效果,和效率.
这里写图片描述

四.备注及总结

设计模式的学习和掌握可以让我们写的代码更加的具有规范性,设计模式仅是一种实现功能的同时让代码更具有规范性的手段,自然不区分语言.
后面继续补充比较常用的其他设计模式.有什么问题还请各位大牛们给出矫正.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值