JAVA设计模式之单例模式

来源:互联网 发布:cisco 查看端口ip 编辑:程序博客网 时间:2024/05/16 02:58

一.简介

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

二.实现

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

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效果,和效率.
这里写图片描述

四.备注及总结

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