Singleton模式的目的:
想要確保任何情況下都絕對只有1個實(shí)例
需要程序表現(xiàn)上“只存在一個實(shí)例”
注意:這個模式在多線程下面使用的時候可能會線程不安全產(chǎn)生多個實(shí)例擂仍,使用的時候需要多加小心
Singleton模式.png
簡單的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("兩個對象相等其障,是同一個實(shí)例對象");
} else {
System.out.println("兩個對象不相等俯邓,不是同一個實(shí)例對象");
}
}
}
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("生成一個實(shí)例!L匝谩!!");
}
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實(shí)例化了.......");
slowdown();
}
public static Singleton getInstance(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
private void slowdown(){
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
}
如何改造成安全的Singleton多線程模式??
方式一:修改獲取實(shí)例的方法舍扰,將其設(shè)置成線程安全模式:public synchronized static Singleton getInstance();
方式二:在設(shè)置靜態(tài)成員變量singleton的時候直接給它賦初始值倦蚪。為什么這種方式可以實(shí)現(xiàn)線程安全?因?yàn)樵诔绦蛐枰玫竭@個類的時候會先去加載初始化這個類边苹,按照類的初始化原則陵且,這個時候的靜態(tài)成員變量在加載初始化類的時候就會被創(chuàng)建分配好內(nèi)存,初始化好數(shù)據(jù)勾给。因?yàn)橹粫a(chǎn)生一個實(shí)例滩报。