1.饿汉式
- 构造器私有化 (防止 new )
- 类的内部创建对象
- 向外暴露一个静态的公共方法。getInstance
public class Singleton1 {
private Singleton1() {
}
private static final Singleton1 single = new Singleton1();
public static Singleton1 getNewStance(){
return single;
}
}
优点:类装载的时候就完成实例化。避免了线程同步问题。
缺点:类装载的时候就完成实例化,如果没有用到实例会造成内存浪费。
2.懒汉式
public class Singleton02 {
private static Singleton02 singleton02;
public static synchronized Singleton02 getNewStance(){
if(singleton02==null){
singleton02 = new Singleton02();
}
return singleton02;
}
}
- 解决了 线程安全问题
- 效率太低了,每个线程在想获得类的实例时候,执行 getInstance()方法都要进行同步。而其实这个方法只执行
一次实例化代码就够了,后面的想获得该类实例,直接 return 就行了。 方法进行同步效率太低 - 结论:在实际开发中, 不推荐使用这种方式
3. 双重检查
public class Singleton03 {
private static volatile Singleton03 singleton3; //将数据强制刷入主内存创建对象后其他线程可以读取到
private Singleton03() {
}
public static Singleton03 getNewStance(){
if(singleton3 == null){
synchronized (Singleton03.class){
if(singleton3 == null){ // 加这个判断防止多线程重复创建对象
singleton3 = new Singleton03();
}
}
}
return singleton3;
}
}
提供一个静态的公有方法,加入双重检查代码,解决线程安全问题, 同时解决懒加载问题同时保证了效率, 推荐使用.
4.静态内部类
public class Singletion04 {
private static class Singletion04Inner {
private static final Singletion04 singletion04 = new Singletion04();
}
public static Singletion04 getNewStance(){
return Singletion04Inner.singletion04;
}
}
静态内部类方式在 Singleton 类被装载时并不会立即实例化,而是在需要实例化时,调用 getInstance 方法,才
会装载 SingletonInstance 类,从而完成 Singleton 的实例化。
类的静态属性只会在第一次加载类的时候初始化。