1.立即加载/"饿汉模式"
什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现办法就是直接new实例化.而立即加载从中文的语境来看,有"着急"/"急迫"的含义,所以也称为"饿汉模式".
/*
* 立即加载方式===饿汉模式
*/
public class SingleObject {private static SingleObject single = new SingleObject();private SingleObject() { }public static SingleObject getInstance() {return single;}public static void main(String[] args) {new Thread(() -> {System.out.println(SingleObject.getInstance().hashCode());}).start();new Thread(() -> {System.out.println(SingleObject.getInstance().hashCode());}).start();new Thread(() -> {System.out.println(SingleObject.getInstance().hashCode());}).start();} }
hashCode是同一值,说明对象是同一个,也就是实现了立即加载型单例模式.
2.延迟加载/"懒汉模式"----在多线程下很容易出现问题
什么是延迟加载?延迟加载就是在调用get()方法时实例才被创建,常见的实现办法就是在get()方法中进行new实例化.而延迟加载从中文的语境来看,是"缓慢"/"不急迫"的含义,所以也称为"懒汉模式".
解决不同步的办法
/*
* 延迟加载----懒汉模式
* 在多线程下的解决办法,使用DCL双检查锁机制
* 效率比较高
*/
public class SingleObject1 {private static SingleObject1 single;private SingleObject1() {}public static SingleObject1 getInstance() {if (single == null) {synchronized (SingleObject1.class) {if (single == null) {single = new SingleObject1();}}}return single;}public static void main(String[] args) {new Thread(() -> System.out.println(SingleObject1.getInstance().hashCode())).start();new Thread(() -> System.out.println(SingleObject1.getInstance().hashCode())).start();new Thread(() -> System.out.println(SingleObject1.getInstance().hashCode())).start();} }
使用双重检查锁功能,成功地解决了"懒汉模式"遇到多线程的问题.DCL也还是大多数多线程结合单例模式使用的解决办法.
3.使用静态内部类实现单例模式
/*
* 通过静态内部类实现单例模式
*/
public class SingleObject2 {private static class SingleHandler {private static SingleObject2 single = new SingleObject2();}private SingleObject2() { }public static SingleObject2 getInstance() {return SingleObject2.SingleHandler.single;}public static void main(String[] args) {new Thread(() -> System.out.println(SingleObject2.getInstance().hashCode())).start();new Thread(() -> System.out.println(SingleObject2.getInstance().hashCode())).start();new Thread(() -> System.out.println(SingleObject2.getInstance().hashCode())).start();new Thread(() -> System.out.println(SingleObject2.getInstance().hashCode())).start();} }
4.序列化与反序列化实现单例模式
静态内部类可以达到线程安全问题,但如果遇到序列化对象时,使用默认的方式运行得到的结果还是多例的.

解决办法就是反序列化中使用readResolve()方法.
5.使用static代码块实现单例模式
静态代码块中的代码在使用类的时候就已经执行了,所以可以应用静态代码块的这个特性来实现单例设计模式.
/*
* 使用静态代码块实现单例模式
*/
public class SingleObject3 {private static SingleObject3 single;public SingleObject3() { }static {single = new SingleObject3();}public static SingleObject3 getInstance() {return single;}public static void main(String[] args) {new Thread(() -> { for(int i = 0 ; i < 5; i++) {System.out.println(SingleObject3.getInstance().hashCode());}}).start();new Thread(() -> { for(int i = 0 ; i < 5; i++) {System.out.println(SingleObject3.getInstance().hashCode());}}).start();} }
6.使用enum枚举数据类型实现单例模式
枚举enum和静态代码块的特性相似,在使用枚举类是,构造方法会被自动调用,也可以应用其这个特性实现单例模式.

上面将枚举类暴露出来了,下面进行完善.
