1. 同步整个方法
同步整个方法,可能会导致不太高效
public class Singleton {
// private 保证不能被类以外引用;
// static 在对象实例化前已分配空间,保证变量唯一性
private static Singleton instance;
// private 构造方法保证不能在类外new
private Singleton() {}
/* static 保证在类外可以直接通过类名来访问方法,
* 而无须创建Singleton对象。
* 事实上在类外也无法创建Singleton对象,
* 因为构造函数是私有的。
**/
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2. 双重检查锁
public class Singleton {
// private 保证不能被类以外引用;
// volatile 禁止new Singleton()时的三条指令重排序
// static 在对象实例化前已分配空间,保证变量唯一性
private volatile static Singleton instance;
// private 构造方法保证不能在类外new
private Singleton() {}
/* static 保证在类外可以直接通过类名来访问方法,
* 而无须创建Singleton对象。
* 事实上在类外也无法创建Singleton对象,
* 因为构造函数是私有的。
**/
public static Singleton getInstance() {
// 第一个if保证高效,减少不必要的同步带来的性能开销
if (instance == null) {
synchronized(Singleton.class) {
// 第二个if保证两个线程同时进去第一个if后,只产生一个Singleton实例
if (null == instance) {
instance = new Singleton();
}
}
}
return instance;
}
}
3. class加载类到内存中时实例化
public class Singleton {
// 类加载时生成实例
private static final Singleton instance = new Singleton();
// private修饰构造方法禁止类外部使用new来创建对象
private Singleton(){}
/** static保证在类外可以直接通过类名来访问,
* 而无须创建Singleton对象。
* 事实上在类外也无法创建Singleton对象,
* 因为构造函数是私有的。
*/
public static Singleton getInstance() {
return instance;
}
}
4. 静态内部类
//1.不用synchronized,所以可以保证性能
//2.只有调用getInstance()方法时才会创建对象所以是懒汉式的
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
// private修饰构造方法禁止类的外部使用new来创建对象
private Singleton (){}
/** static保证在类外可以直接通过类名来访问,
* 而无须创建Singleton对象。
* 事实上在类外也无法创建Singleton对象,
* 因为构造函数是私有的。
*/
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
5. 枚举单例
public enum Singleton {
// 默认为public static final类型
INSTANCE;
// 隐藏了private类型的私有构造方法
// private Singleton() {}
}
implements接口的形式实现单例模式
interface Foo {
// 单例模式的方法,实现类中实现代码逻辑
void doSomething();
}
public enum Singleton implements Foo {
INSTANCE {
@Override
public void doSomething() {
System.out.println("单例的方法");
}
};
public static Foo getInstance() {
return Singleton.INSTANCE;
}
public static void main(String[] args) {
Foo a = Singleton.getInstance();
a.doSomething();
}
}
网友评论