Singleton模式的目的:
想要確保任何情況下都絕對只有1個實例
需要程序表現上“只存在一個實例”
注意:這個模式在多線程下面使用的時候可能會線程不安全產生多個實例,使用的時候需要多加小心
簡單的Singleton模式案例:
Main.java
package one;
/**
* @Author:DarknessShadow
* @description:主測試程序
* @date 2020/5/12 9:32
*/
public class Main {
public static void main(String[] args) {
System.out.println("start.....");
Singleton singleton = Singleton.getInstance();
Singleton singleton1 = Singleton.getInstance();
if (singleton == singleton1) {
System.out.println("兩個對象相等,是同一個實例對象");
} else {
System.out.println("兩個對象不相等,不是同一個實例對象");
}
}
}
Singleton.java
package one;
/**
* @Author:DarknessShadow
* @description:單線程單例模式
* @date 2020/5/12 9:32
*/
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){
System.out.println("生成一個實例!!!!");
}
public static Singleton getInstance(){
return singleton;
}
}
多線程不安全模式下的Singleton模式案例:
Main.java
package two;
/**
* @Author:DarknessShadow
* @description:主測試程序
* @date 2020/5/12 10:23
*/
public class Main extends Thread {
public static void main(String[] args) {
System.out.println("start.....");
new Main("A").start();
new Main("B").start();
new Main("C").start();
new Main("D").start();
System.out.println("End.....");
}
public void run(){
Singleton singleton = Singleton.getInstance();
System.out.println(getName() + ": obj = " + singleton);
}
public Main(String name) {
super(name);
}
}
Singleton.java
package two;
/**
* @Author:DarknessShadow
* @description:多線程單例模式,線程不安全
* @date 2020/5/12 10:23
*/
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
System.out.println("singleton實例化了.......");
slowdown();
}
public static Singleton getInstance(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
private void slowdown(){
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
如何改造成安全的Singleton多線程模式??
方式一:修改獲取實例的方法,將其設置成線程安全模式:public synchronized static Singleton getInstance();
方式二:在設置靜態成員變量singleton的時候直接給它賦初始值。為什么這種方式可以實現線程安全?因為在程序需要用到這個類的時候會先去加載初始化這個類,按照類的初始化原則,這個時候的靜態成員變量在加載初始化類的時候就會被創建分配好內存,初始化好數據。因為只會產生一個實例。