单例模式:目的是保证一个类只能有一个实例,而且自行实例化并向整个系统提供这个实例,避免频繁创建对象,节约内存
饿汉式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
public class Singleton implements Serializable { private Singleton(){ System.out.println("private Singleton"); } //给static变量赋值最终会在static静态代码块里执行,java虚拟机会保证线程安全 private static final Singleton INSTANCE=new Singleton(); public static Singleton getInstance(){ return INSTANCE; } public static void otherMethod(){ System.out.println("otherMethod"); } } //防止反射破坏单例模式: public class Singleton1 implements Serializable { private Singleton1(){ if(INSTANCE!=null){ throw new RuntimeException("单例对象不能重复创建"); } } private static final Singleton1 INSTANCE=new Singleton1(); public static Singleton1 getInstance(){ return INSTANCE; } public static void otherMethod(){ System.out.println("otherMethod"); } public Object readResolve(){ return INSTANCE; } } public enum SingletonByEnum { INSTANCE; //枚举类的构造默认是private SingletonByEnum(){ System.out.println("private SingletonByEnum()"); } public static SingletonByEnum getInstance(){ return INSTANCE; } public static void otherMethod(){ System.out.println("otherMethod"); } @Override public String toString(){ return getClass().getName()+"@"+Integer.toHexString(hashCode()); } }
懒汉式:在类加载时不初始化,等到第一次被使用时才初始化。
public class Singleton3 implements Serializable { private Singleton3(){ System.out.println("private Singleton3()"); } //volatile多线程可见性和有序性,这里主要是解决有序性 //有可能INSTANCE还没有构造完就把对象赋值给了INSTANCE,那这时候调用就会出现很多问题 //因此加上volatile保证已经构造完了在把对象赋值给INSTANCE。 private static volatile Singleton3 INSTANCE=null; public static Singleton3 getInstance(){ if(INSTANCE==null){ synchronized (Singleton3.class){ if (INSTANCE==null){ INSTANCE=new Singleton3(); } } } return INSTANCE; } public static void otherMethod(){ System.out.println("otherMethod"); } } public class Singleton2 implements Serializable { private Singleton2(){ System.out.println("private Singleton2()"); } //在静态方法里,会在静态代码块里执行,jdk会保证线程安全 private static class Holder{ static Singleton2 INSTANCE=new Singleton2(); } public static Singleton2 getInstance(){ return Holder.INSTANCE; } public static void otherMethod(){ System.out.println("otherMethod"); } }
在jdk中哪里使用了单例模式:
gc()方法: 饿汉式单例模式
public static void gc() { Runtime.getRuntime().gc(); } public class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } }
console() 双检索懒汉式:
private static volatile Console cons = null; public static Console console() { Console c; if ((c=cons) == null) { synchronized (System.class) { if((c=cons) == null){ cons=c = SharedSecrets.getJavaIOAccess().console(); } } } return c; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)