关于单例模式,相信大家都是相当的熟悉,也用的特别多,它是用的最广的模式之一。尽管如此,我们还是来对它进行一些总结。它主要有以下特点:
- 只能有一个实例。如果有多个实例,那就不叫单例模式了。
- 这个唯一的实例必须由自己来创建。
- 单例类给所有的其它对象提供这个一实例。
那么我们基于三个特点,我们基本可以归纳出在程序中的三个特点:
- 构造函数私有。如果构造函数不设置成private,那么就可以在其它类中用new的方式来创建实例,就不能实例的个数唯一。
- 提供实例的方法必需要是static的。既然无法在其它类中创建实例,那么要调用单例中的方法,就只能保证这个方法是静态(static)的。
- synchronized,主要考虑到多线程环境下的问题。
明白了上面几点,相信单例模式,你几基本上已经理会了。接下来,我们看看实例单例模式的几种方式:
饿汉式:
package com.pattern.singleton;
/**
* 饿汉式
*/
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
/**
* 私有构造函数
*/
private EagerSingleton(){}
/**
* 静态工厂方法,提供给对外使用
* @return
*/
public static EagerSingleton getInstance(){
return instance;
}
}
懒汉式:
package com.pattern.singleton;
/**
* 懒汉式
*/
public class LazySingleton {
private LazySingleton(){}
private static LazySingleton instance = null;
public static synchronized LazySingleton getInstance(){
if(instance ==null){
instance = new LazySingleton();
}
return instance;
}
}
这两种方式的区别都明显,饿汉式是类第一次加载的时候,便创建好实例,以后都只管获取就行了。而懒汉式,顾名思议,比较懒,单例类说:你不来找我要,我才懒得帮你创建列。 那么,他是在第一获取实例的时候,创建实例。为了考虑在多线程环境下的问题,所以我们加上了synchronized。
其实GOF还提出了另外一种实现方式:登记式,不过个人觉得这种方式缺点太多,而且不是很严谨,所以没打算拿出来说。
因此、单例模式使用的环境我们就很清楚了:整个应用中,某个类要求只有一个实例时,才能使用。
在JDK中,最典型的就是Runtime类,他就是一个典型的单例模式的应用,他的部分代码如下:
public class Runtime {
private static Runtime currentRuntime = new Runtime();
/**
* Returns the runtime object associated with the current Java application.
* Most of the methods of class <code>Runtime</code> are instance
* methods and must be invoked with respect to the current runtime object.
*
* @return the <code>Runtime</code> object associated with the current
* Java application.
*/
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
现在我们就来应用RunTime类来打开记事本:
package com.pattern.singleton;
import java.io.IOException;
public class CmdTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Process proc = Runtime.getRuntime().exec("notepad.exe");
}
}
当然了,在JDK中还有很多应用了单例模式的类库,我们就不一一举例了。