1、 用“双双重检查加锁”,在个体Instance()中减少使用同步
利用双重检查加锁,首先检查是否实例已经创建了,如果尚未创建,“才”进行同步。这样一来,只有第一次回同步,这正是我们想要的。
来看看代码:
public class Singleton {
private volatile static Singleton singleton;//volatile关键字确保,当singleton变量被初始化成Singleton实例时,多个线程正确地处理singleton变量
public static Singleton getInstance()
{
//synchronized为了防止多线程同时进入此操作,虽然同步会降低性能(调用)
//如果把同步放在方法上会造成性能降低,只有第一次执行此方法,才真正的需要同步
换句话说,一旦设置好singleton变量,就不再需要同步这个方法了,之后每次的调用这个
方法,同步都是一种累赘。所以放在里面比较好
if (singleton == null) {//双重监测加锁
synchronized (Singleton.class) {//在此进行限制只有一个线程
if (singleton == null) {
singleton = new Singleton();
}
}
singleton= new Singleton();
}
return singleton;
}
}
2、使用须知
- 单件模式确保程序中一个类最多只有一个实例
- 单件模式也提供访问这个实例的全局点
- 在Java中实现单件模式需要私有的构造器、一个静态方法和一个静态变量。
- 确定在性能和资源上的限制,然后小心的选择适当的方案来实现单件,已解决多线程的问题(我们必须认定所有的程序都是多线程的)
- 如果不是采用第五版的Java 2,双重检查加锁实现会失效。
- 小心,你如果使用多个类加载器,可能导致单件失效而产生多个实例。你可以指定一个类加载器进行避免。
- 如果使用JVM 1.2或之前的版本,你必须建立单件注册表,以避免垃圾收集器将单件收回
转载自head frist 设计模式第五章