【第3条:用私有够在其或者枚举类型强化Singleton属性】
其实《effective java》这一节讲其实就是单例模式。书中的例子提到饿汉式和枚举单例。
那么就出现三种单例模式:饿汉式、懒汉式、枚举。
关于单例模式的应用场景可以看下这篇文章:http://blog.youkuaiyun.com/tanyujing/article/details/14160941
饿汉式
是否 Lazy 初始化:否
是否多线程安全:是
实现难度:易
描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
它基于 classloder 机制避免了多线程的同步问题,不过,instance 在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用 getInstance 方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化 instance 显然没有达到 lazy loading 的效果。
public class Util {
private static Util util = new Util();
/**
* 饿汉式写法,一般情况下使用
* @return
*/
public static Util GetInstance(){
return util;
}
/**
* 判断是否手机电话号码
* @param str
* @return
*/
public boolean IsMobilePhoneNum(String str){
Pattern pattern = Pattern.compile("^(1)\\d{10}$");
Matcher matcher=null;
if (str!=null&&!str.isEmpty()) {
matcher = pattern.matcher(str);
}
return matcher.find();
}
}
懒汉式是否 Lazy 初始化:是
是否多线程安全:是
实现难度:易
描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。
优点:第一次调用才初始化,避免内存浪费。
缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。
getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。
public class Util {
private static Util util;
/**
* 懒汉式写法,synchronized修饰保证线程同步
*
* @return
*/
public static synchronized Util GetInstance() {
if (util == null) {
util = new Util();
}
return util;
}
/**
* 判断是否手机电话号码
*
* @param str
* @return
*/
public boolean IsMobilePhoneNum(String str) {
Pattern pattern = Pattern.compile("^(1)\\d{10}$");
Matcher matcher = null;
if (str != null && !str.isEmpty()) {
matcher = pattern.matcher(str);
}
return matcher.find();
}
}
枚举单例
JDK 版本:JDK1.5 起
是否 Lazy 初始化:否
是否多线程安全:是
实现难度:易
描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
public enum Elvis{
instance;
private int i=0;
public void doSomeThing(){
i++;
System.out.println(i);
System.out.println("doSomeThing");
}
}
使用示例
for (int i = 0; i < 10; i++) {
Elvis.instance.doSomeThing();
}