good good study, day day up!

Java单例模式(Singleton)

2011-11-12

Java单例模式是指:某个类在运行时只能生成唯一的一个实例.
也就是说,如果我们使用传统的new关键字来创建类的实例的话肯定是无法实现单例模式的(我们可以用new关键字创建无数个实例,如果内存足够的话).

所以我们要使new关键字失效,最简单的方法就是为类提供惟一的一个构造方法(Constructor),并将该构造方法设置为私有(private):

private constructor(){}

这样一来我们就对外部关闭了构造函数,外部程序无法通过正常手段(new关键字)来创建实例.

但是这样一来我们就无法获取到该类的实例了,因为我们连一个实例都无法获取.

现在我们的类只有一个私有的构造函数,我们只能从类的内部来创建一个实例,然后通过一个公共(public)的静态(static)方法将该实例返回给外部程序:

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

如此一来我们便可通过调用getInstance()方法来获取到类的唯一一个实例了:

Singleton s = Singleton.getInstance();

另外一种实现方式如下:

public class Singleton{
    private static Singleton singleton;
    private Singleton(){}
    public static Singleton getInstance(){
        if(singleton == null){
        singleton = new Singleton();
        }
        return singleton;
    }
}

比较两种方式,我们发现,两种方法都是在类中存一个静态的对实例的引用,不同的是,第一种方法在类第一次被加载的时候就将singleton声明并赋值,第二种是在getInstance方法中判断singleton是否已赋值,如果没有则赋值并返回,如果已赋值则直接返回.两种方法乍一看区别不大,但是这里建议大家使用第一种方法,也就是预先实例化然后只需要返回引用.提出这个建议的原因是当我们使用Java多线程时,第一种方法是线程安全的,第二种方法是有危险的.具体细节以后我会在新的日志中细说,这里只是提出建议.

下面我们通过一个程序看一看我们的单例模式是否已经实现:

public class Client {
    public static void main(String[] args) {
    Singleton singleton1 = Singleton.getInstance();
    Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton1 == singleton2);
    }
}

输出结果为:

true

证明我们用上述方法确实实现了单例模式.

 


知识共享许可协议本作品采用知识共享署名 2.5 中国大陆许可协议进行许可,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名(chen)并包含原文链接

作者:chending | Categories:Java | Tags:

2条评论

  1. Renee说道:

    强啊!我顶一个!

Zuo Chairs进行回复 取消回复

电子邮件地址不会被公开。 必填项已用*标注