使用枚举实现代码如下:
枚举类(推荐)
1 public enum SomeThing { 2 3 INSTANCE; 4 private Resource instance; 5 6 SomeThing() { 7 instance = new Resource(); 8 } 9 10 public Resource getInstance() { 11 return instance; 12 } 13 }
对象类
1 public class Resource { 2 }
main方法
1 public static void main(String[] args) { 2 Resource instance1 = SomeThing.INSTANCE.getInstance(); 3 System.out.println(instance1); 4 Resource instance = SomeThing.INSTANCE.getInstance(); 5 System.out.println(instance); 6 }
输出结果
1 com.itheima.test.Resource@697446d4 2 com.itheima.test.Resource@697446d4
使用静态内部内实现
代码如下
1 public class SingletonTest { 2 /** 私有化构造器 */ 3 private SingletonTest() { 4 } 5 6 /** 对外提供公共的访问方法 */ 7 public static SingletonTest getInstance() { 8 return UserSingletonHolder.INSTANCE; 9 } 10 11 /** 写一个静态内部类,里面实例化外部类 */ 12 private static class UserSingletonHolder { 13 private static final SingletonTest INSTANCE = new SingletonTest(); 14 } 15 }
main方法
1 public static void main(String[] args) { 2 3 SingletonTest instance = SingletonTest.getInstance(); 4 System.out.println(instance); 5 6 SingletonTest instance1 = SingletonTest.getInstance(); 7 System.out.println(instance1); 8 }
结果
1 com.itheima.test.SingletonTest@1ab06251 2 com.itheima.test.SingletonTest@1ab06251
懒汉模式
代码如下
1 public class SingletonTest { 2 //懒汉式单例类.在第一次调用的时候实例化自己 3 private SingletonTest() {} 4 private static SingletonTest single=null; 5 //静态工厂方法 6 public static SingletonTest getInstance() { 7 if (single == null) { 8 single = new SingletonTest(); 9 System.out.println("创建一次"); 10 } 11 return single; 12 } 13 public void show(){ 14 System.out.println("我是show"); 15 } 16 }
main方法
1 public static void main(String[] args) { 2 //故意写获取两次,创建两个对象 3 SingletonTest singleton = SingletonTest.getInstance(); 4 SingletonTest singleton2 = SingletonTest.getInstance(); 5 6 //Singleton对象只创建一次,但是写两次还是可以的,而且方法都是可以调用的,但是看下面 7 singleton.show(); 8 singleton2.show(); 9 10 //两个对象的表现形式一样 11 if (singleton == singleton2) { 12 System.out.println("该对象的字符串表示形式:"); 13 System.out.println("singleton :" + singleton.toString()); 14 System.out.println("singleton2:" + singleton2.toString()); 15 } 16 }
结果
1 创建一次 2 我是show 3 我是show 4 该对象的字符串表示形式: 5 singleton :com.itheima.test.SingletonTest@1ab06251 6 singleton2:com.itheima.test.SingletonTest@1ab06251
饿汉模式
代码如下
1 public class SingletonTest { 2 private SingletonTest() {} 3 private static final SingletonTest single = new SingletonTest(); 4 //静态工厂方法 5 public static SingletonTest getInstance() { 6 return single; 7 } 8 }
main方法
1 public static void main(String[] args) { 2 SingletonTest instance = SingletonTest.getInstance(); 3 System.out.println(instance); 4 5 SingletonTest instance1 = SingletonTest.getInstance(); 6 System.out.println(instance1); 7 }
双重检测锁模式
代码如下
1 public class Singleton { 2 private volatile static Singleton singleton; 3 private Singleton (){} 4 public static Singleton getSingleton() { 5 if (singleton == null) { 6 synchronized (Singleton.class) { 7 if (singleton == null) { 8 singleton = new Singleton(); 9 } 10 } 11 } 12 return singleton; 13 } 14 }
总结
1. 饿汉式 线程安全,调用效率高 ,但是不能延迟加载 2. 懒汉式 线程安全,调用效率不高,能延迟加载 3. 双重检测锁式 由于JVM底层内部模型原因,偶尔会出问题。不建议使用 4. 静态内部类式 线程安全,资源利用率高,可以延时加载 5. 枚举单例 线程安全,调用效率高,但是不能延迟加载