几个项目下来,对于设计模式还是比较熟悉了,比如什么适配器模式,工厂模式,单例模式,什么原型模式等等。
但是,对于单例模式还是有些东西可以好好说一下的。比如,写一个简单的单例模式的例子。下面的代码应该是大多数人的选择:
public class Singleton_Test_1{
public Singleton_Test_1() {
System.out.println("I was built");
}
private static Singleton_Test_1 singleton_Test_1 = new Singleton_Test_1();
public static Singleton_Test_1 getInstance() {
return singleton_Test_1;
}
}
乍一看,确实没什么错误。但是,如果你的类中有一个简单的方法,比如:
public static void doSomething() {
System.out.println("We don't need singleton_Test_1");
}
那么,此时会发生什么呢?
很显然,类被创建了,但是,这个方法我们倾向于不创建单例类,而且在使用的时候可能会降低程序的反应速度。
所以我们有了这么一个东西:
public class Singleton_Test_2 {
public Singleton_Test_2() {
System.out.println("I was built");
}
private static Singleton_Test_2 singleton_Test_2 = null;
public static Singleton_Test_2 getInstance() {
if (singleton_Test_2 == null) {
singleton_Test_2 = new Singleton_Test_2();
}
return singleton_Test_2;
}
}
用一个延迟加载就能解决问题,但是,仔细看看,这个程序有没有毛病呢?其实还是有的,如果在多线程环境下,第一次调用的时候,很容易产生多个实例,这就是我们不愿意看到了。
所以,我们加了一个同步化。就像这样:
public static synchronized Singleton_Test_2 getInstance() {
if (singleton_Test_2 == null) {
singleton_Test_2 = new Singleton_Test_2();
}
return singleton_Test_2;
}
很简单的解决了问题,但是效率呢?不敢恭维。
怎么办呢?现在隆重推出Holder!看代码:
public class Singleton_Test_3 {
public Singleton_Test_3() {
System.out.println("Singleton_Test_3 was built");
}
private static class singletonHolder{
private static Singleton_Test_3 instance = new Singleton_Test_3();
}
public static Singleton_Test_3 getInstance() {
return singletonHolder.instance;
}
}
在这个方法中,我们使用了内部类进行对实例的管理,这样既防止了不必要的构造,也可以加快读取速度。下面是我的测试代码,大家可以看看。
public class Singleton {
/**
* @author mikecoder
* @see http://d0n9x1n.dev
*/
public static void main(String[] args) {
//Singleton_Test_1.doSomething();
//Singleton_Test_2.doSomething();
//Singleton_Test_3.doSomething();
long time1 = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
Singleton_Test_1 singleton_Test_1 = Singleton_Test_1.getInstance();
}
System.out.println(System.currentTimeMillis() - time1);
time1 = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
Singleton_Test_2 singleton_Test_2 = Singleton_Test_2.getInstance();
}
System.out.println(System.currentTimeMillis() - time1);
time1 = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
Singleton_Test_3 singleton_Test_3 = Singleton_Test_3.getInstance();
}
System.out.println(System.currentTimeMillis() - time1);
}
}
结果是:
dosomething:
效率:
所以,这一次就讲到这里。

