方法一:
public class Singleton1 { private Singleton1(){ System.out.print("Singleton1 created"); } private static Singleton1 instance = new Singleton1(); public static Singleton1 getInstance(){ return instance; } public static void createString(){ System.out.print("String created"); }}
当使用Singleton.createString()时执行结果如下:
Singleton createdString created
虽然并没有使用单例类,但还是被加载出来了。为了解决这个问题我们引入方法二。
方法二:
public class Singleton2 { private Singleton2(){ System.out.print("Singleton2 created"); } private static Singleton2 instance = null; public static sychronized Singleton2 getInstance(){ if (install == null){ instance = new Singleton2(); } return instance; }}
第二种方法使用了同步关键字,实现了延迟加载功能,但是由于同步关键字是不允许多个线程同事访问被sychronized修饰的代码,所以可想而知在多线程的项目中他的效率还不如方法一(此处可以自己验证)。
方法三:
public class Singleton3 { private Singleton(){ System.out.print("Singleton3 created"); } private static class SingletonHolder { private static Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance() { return SingletonHolder.instance; }}
在Singleton3中,单例模式使用内部类来维护单例的实例,当Singleton3被加载时,其内部类不会被加载,而当getInstance方法调用时,才会加载SingletonHolder类,保证了延迟加载的功能。
方法四:
//线程锁单列模式public class Singleton4 { private Singleton(){ System.out.print("Singleton4 created"); } public volatile static Singleton4 instance; public static Singleton4 getInstance() { if(instance == null){//已存在的线程效率较高 sychronized(Singleton4.class){ if(instance == null){ instance = new Singleton4(); } } } return instance; }}