1.餓汗式
1.1常規方式
/** * 餓汗式單例 * 特點: * 1.在类初始化时直接创建实例对象,不管你是否需要这个对象都会创建 * 2.線程是安全的 * 步驟: * 1)構造函數私有化 * 2)自行創建實例,並且用靜態變量保存 * 3)向外提供這個實例 * 4)強調這個是單例可以用final修飾 */
public class Singleton1 { private Singleton1() { } public static final Singleton1 INSTANCE = new Singleton1(); //類加載初始化時就會創建 }
1.2枚舉方式
/*** * 枚舉類型:表示该类型的对象是有限的几个 * 我们可以限定为一个,就成了单例 * */ public enum Singleton2 { INSTANCE //枚舉類型的構造器全部都是私有的 }
1.3.靜態代碼塊
/** * 靜態代碼塊 * 這種應用場景一般是在靜態代碼塊中要獲取一些指定的數據 * 例如下面,要獲取指定的classes下指定的info.properties文件 * 此時我們可以使用以下方式獲取,springboot項目放在resources下面,這樣解析成class時就會在classes下面 */ public class Singleton3 { public static final Singleton3 INSTANCE; private String info; static { try { Properties pro = new Properties(); pro.load(Singleton3.class.getClassLoader().getResourceAsStream("info.properties")); INSTANCE = new Singleton3(pro.getProperty("info")); } catch (IOException e) { throw new RuntimeException(); } } private Singleton3(String info) { this.info = info; } }
2.懶漢式
2.1 線程安全的懶漢式
/** * f3851884 2023/3/8 * 懶漢式單例 * 延迟创建这个实例对象 * 1)構造器私有化 * 2)用一個靜態的變量保存這個唯一的實例 * 3)提供一個靜態方法,獲取這個實例對象 * * */ public class Singleton4 { private static Singleton4 instance; private Singleton4(){ } public static Singleton4 getInstance(){ if(instance == null){ synchronized(Singleton4.class){ if(instance == null){ instance = new Singleton4(); } } } return instance; } }
2.2 使用內部類實現單例
/* * 在内部类被加载和初始化时,才创建INSTANCE实例对象 * 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要单独去加载和初始化的。 * 因为是在内部类加载和初始化时,创建的,因此是线程安全的 */ public class Singleton6 { private Singleton6(){} private static final class Inner{ private static Singleton6 INSTANCE = new Singleton6(); } public static Singleton6 getInstance(){ return Inner.INSTANCE; } }