饿汉式的不足是直接给你加载了对象,如果你确定会使用其加载的对象,就不会造成内存浪费,那么也是推荐使用的。如 java中 的RunTime类 就是饿汉式单例模式。
静态内部类或者枚举型写的单例模式都是懒加载的,且线程安全。推荐使用。
public class SingletonTest01 {
public static void main (String[] args){
System.out.println( SingletonHungryStyle.getInstance());
System.out.println( SingletonSluggardStyle.getInstance());
SingletonEnum.INSTANCE.run();
}
}
//饿汉式 缺点:默认创建对象,容易造成内存浪费
class SingletonHungryStyle {
//1.构造器私有化,外部不能new
private SingletonHungryStyle(){}
//2.本内内部创建对象实例
private final static SingletonHungryStyle instance = new SingletonHungryStyle();
//3.提供公有的静态方法,返回实例对象
public static SingletonHungryStyle getInstance(){
return instance;
}
}
//懒汉类(缺点:线程不安全 if判断时 线程不安全)
class SingletonSluggardStyle{
private static SingletonSluggardStyle instance;
private SingletonSluggardStyle(){}
//当用到该方法时,才去创建instance
public static SingletonSluggardStyle getInstance() {
if (instance == null) {
instance = new SingletonSluggardStyle();
}
return instance;
}
}
//懒汉类_同步安全型(缺点:同步,所以效率低)
class SingletonSluggardStyle_Synchronized{
private static SingletonSluggardStyle_Synchronized instance;
private SingletonSluggardStyle_Synchronized(){}
//synchronized 解决线程安全问题。保证了getInstance方法执行完毕。
public static synchronized SingletonSluggardStyle_Synchronized getInstance() {
if (instance == null) {
instance = new SingletonSluggardStyle_Synchronized();
}
return instance;
}
}
//单例模式 双重检查 安全(推荐使用)
class SingletonSluggardStyle_doubleCheck{
//volatile关键字会强制将修改的值立即写入主存
private static volatile SingletonSluggardStyle_doubleCheck instance;
private SingletonSluggardStyle_doubleCheck(){}
//synchronized 解决线程安全问题。保证了getInstance方法执行完毕。
public static synchronized SingletonSluggardStyle_doubleCheck getInstance() {
if (instance == null) {
synchronized(SingletonSluggardStyle_doubleCheck.class){
if (instance == null) {
instance = new SingletonSluggardStyle_doubleCheck();
}
}
}
return instance;
}
}
//单例 静态内部类 安全 懒加载 推荐使用
class SingletonSluggardStyle_staticInnerClass{
private SingletonSluggardStyle_staticInnerClass(){ }
private static class SingletonSluggardStyle_staticInnerClassInstance{
private static SingletonSluggardStyle_staticInnerClass instance = new SingletonSluggardStyle_staticInnerClass();
}
//当调用getInstance时,SingletonSluggardStyle_staticInnerClassInstance被装载,只装载一次,且线程安全。
public static SingletonSluggardStyle_staticInnerClass getInstance() {
return SingletonSluggardStyle_staticInnerClassInstance.instance;
}
}
//枚举类型的单例模式 推荐使用
enum SingletonEnum{
INSTANCE;
public void eat() {
System.out.println("吃饭!!!");
}
public void run() {
System.out.println("跑步!!!");
}
}