而是在需要实例化时,调用getInstance()方法,才会装载内部类,从而完成对象实例化。
import java.io.Serializable; public class Singleton6 implements Serializable { private static final long serialVersionUID = 1L; private Singleton6() { System.out.println("饿汉式优化(静态内部类),推荐用"); } private static class SingletonInstance { private static final Singleton6 INSTANCE = new Singleton6(); } public static Singleton6 getInstance() { return SingletonInstance.INSTANCE; } // 如果该对象被用于序列化,该方法可以保证对象在序列化前后保持一致 private Object readResolve() { return getInstance(); } } 枚举枚举方法不仅保证了线程安全问题,还提供了序列化机制。
public enum Singleton7 { INSTANCE; private Singleton7() { System.out.println("枚举,最好方法"); } public static Singleton7 getInstance() { return INSTANCE; } } 测试 线程安全测试 public class TestSafety { static Singleton1 s1_a; static Singleton1 s1_b; static Singleton2 s2_a; static Singleton2 s2_b; static Singleton3 s3_a; static Singleton3 s3_b; static Singleton4 s4_a; static Singleton4 s4_b; static Singleton5 s5_a; static Singleton5 s5_b; static Singleton6 s6_a; static Singleton6 s6_b; static Singleton7 s7_a; static Singleton7 s7_b; public static void getS1_A() { s1_a = Singleton1.getInstance(); } public static void getS1_B() { s1_b = Singleton1.getInstance(); } public static void getS2_A() { s2_a = Singleton2.getInstance(); } public static void getS2_B() { s2_b = Singleton2.getInstance(); } public static void getS3_A() { s3_a = Singleton3.getInstance(); } public static void getS3_B() { s3_b = Singleton3.getInstance(); } public static void getS4_A() { s4_a = Singleton4.getInstance(); } public static void getS4_B() { s4_b = Singleton4.getInstance(); } public static void getS5_A() { s5_a = Singleton5.getInstance(); } public static void getS5_B() { s5_b = Singleton5.getInstance(); } public static void getS6_A() { s6_a = Singleton6.getInstance(); } public static void getS6_B() { s6_b = Singleton6.getInstance(); } public static void getS7_A() { s7_a = Singleton7.getInstance(); } public static void getS7_B() { s7_b = Singleton7.getInstance(); } public static void main(String[] args) { Thread t1_a = new Thread(TestSafety::getS1_A); Thread t1_b = new Thread(TestSafety::getS1_B); t1_a.start(); t1_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s1_a == s1_b ? " + (s1_a == s1_b)); System.out.println(); Thread t2_a = new Thread(TestSafety::getS2_A); Thread t2_b = new Thread(TestSafety::getS2_B); t2_a.start(); t2_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s2_a == s2_b ? " + (s2_a == s2_b)); System.out.println(); Thread t3_a = new Thread(TestSafety::getS3_A); Thread t3_b = new Thread(TestSafety::getS3_B); t3_a.start(); t3_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s3_a == s3_b ? " + (s3_a == s3_b)); System.out.println(); Thread t4_a = new Thread(TestSafety::getS4_A); Thread t4_b = new Thread(TestSafety::getS4_B); t4_a.start(); t4_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s4_a == s4_b ? " + (s4_a == s4_b)); System.out.println(); Thread t5_a = new Thread(TestSafety::getS5_A); Thread t5_b = new Thread(TestSafety::getS5_B); t5_a.start(); t5_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s5_a == s5_b ? " + (s5_a == s5_b)); System.out.println(); Thread t6_a = new Thread(TestSafety::getS6_A); Thread t6_b = new Thread(TestSafety::getS6_B); t6_a.start(); t6_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s6_a == s6_b ? " + (s6_a == s6_b)); System.out.println(); Thread t7_a = new Thread(TestSafety::getS7_A); Thread t7_b = new Thread(TestSafety::getS7_B); t7_a.start(); t7_b.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("s7_a == s7_b ? " + (s7_a == s7_b)); System.out.println(); } }输出结果:
饿汉式,可用 s1_a == s1_b ? true 懒汉式,线程不安全,多线程不可用 懒汉式,线程不安全,多线程不可用 s2_a == s2_b ? false 懒汉式(synchronized方法),效率太低 s3_a == s3_b ? true 懒汉式(synchronized代码块),线程不安全,多线程不可用 懒汉式(synchronized代码块),线程不安全,多线程不可用 s4_a == s4_b ? false 懒汉式优化(Double Check Lock)双重校验锁,推荐用 s5_a == s5_b ? true 饿汉式优化(静态内部类),推荐用 s6_a == s6_b ? true 枚举,最好方法 s7_a == s7_b ? true 序列化测试只对双重校验锁、静态内部类、枚举测试。