1.最简单的方式,快速加载模式
package com.aloe.pattern.singleton;
/**
* 最简单的实现
* @author chenxing
*
* 此方法为 饥饿式单例模式
*
* 不足之处:SingletonClass1类在被加载的时候,无论这个类有没有用到,都会创造一个实例对象。
* 加入创建这个对象可能要花很长时间,而且又用不到,那么这个单例模式是没有无用的,是没有意义的
*
*/
public class SingletonClass1 {
private static final SingletonClass1 singleton= new SingletonClass1();
//避免用new 获取 对象实例
private SingletonClass1(){
}
public static SingletonClass1 getInstance(){
return singleton;
}
}
2. 懒汉式加载模式
package com.aloe.pattern.singleton;
/**
* 懒汉式单例模式 -- lazy load
* @author chenxing
* 缺点: 如果是单线程,是没有问题的。如果是多线程,其中一个线程刚获取instance还没有来得及赋值,
* 另一个线程也调用getInstance方法,然后那是还是为null,又new一个对象。所以就不是单例了
*
*/
public class SingletonClass2 {
private static SingletonClass2 singleton = null;
private SingletonClass2(){
}
public static SingletonClass2 getInstance(){
if(singleton == null){
singleton = new SingletonClass2();
}
return singleton;
}
}
3. 同步getInstance()方法
package com.aloe.pattern.singleton;
/**
* 同步: 80%的错误都是20%的优化导致的
* @author Administrator
* 同步已经解决了多线程调用getInstance导致的多个bean的现场。
* 但是getInstance的同步块代码会比一般的代码慢上好几倍,如果存在多次调用,那性能肯定会大受影响
*/
public class SingletonClass3 {
private static SingletonClass3 singleton = null;
private SingletonClass3(){
}
public synchronized SingletonClass3 getInstance(){
if(singleton == null){
singleton = new SingletonClass3();
}
return singleton;
}
}
4. double-checked locking ,双重检查锁定 --两个if检查和一个synchronized
package com.aloe.pattern.singleton;
/**
* double-checked locking 双重检查锁定
* @author chenxing
* 最好的单例模式形式
*/
public class SingletonClass4 {
private static SingletonClass4 singleton = null;
private SingletonClass4() {
}
public SingletonClass4 getInstance() {
//线程A,线程B同时进入判断
if (singleton == null) {
//A,B开始同步
synchronized (this) {
//再进一步判断是否为null,如果不判断,会A,B获取的实例不相同
if (singleton == null) {
singleton = new SingletonClass4();
}
}
}
return singleton;
}
}