1、單例模式(立即載入、延時載入)
阿新 • • 發佈:2019-01-09
A、餓漢模式
package demo;
/**
* Created by sunyifeng on 17/10/19.
*/
public class ObjectA {
// 餓汗模式(立即載入)
private static ObjectA myObject = new ObjectA();
public ObjectA() {
// do noting
}
public static ObjectA getInstance() {
return myObject;
}
}
package demo;
/**
* Created by sunyifeng on 17/10/19.
*/
public class ThreadA extends Thread {
@Override
public void run() {
super.run();
System.out.println(ObjectA.getInstance());
}
}
package demo;
/**
* Created by sunyifeng on 17/10/19.
*/
public class RunA {
public static void main(String[] args) {
ThreadA threadA1 = new ThreadA();
ThreadA threadA2 = new ThreadA();
ThreadA threadA3 = new ThreadA();
threadA1.start();
threadA2.start();
threadA3.start();
}
}
執行結果:
[email protected]
[email protected]
[email protected]
程式分析:
1、餓漢模式,例項變數賦值給靜態變數,在被呼叫之前,類載入的時候即建立例項;
2、執行結果執行緒三個執行緒呼叫的是同一個例項;
2、該模式的缺點是如果有其他例項變數,不能保證執行緒安全。
B、懶漢模式
package demo;
/**
* Created by sunyifeng on 17/10/19.
*/
public class ObjectB {
// 懶漢模式(延時載入)
private volatile static ObjectB myObject2;
private ObjectB() {
}
public static ObjectB getInstance() {
try {
Thread.sleep(3000);
synchronized (ObjectB.class) {
if (myObject2 == null) {
myObject2 = new ObjectB();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return myObject2;
}
}
package demo;
/**
* Created by sunyifeng on 17/10/19.
*/
public class ThreadB extends Thread {
@Override
public void run() {
super.run();
System.out.println(ObjectB.getInstance());
}
}
package demo;
/**
* Created by sunyifeng on 17/10/19.
*/
public class RunB {
public static void main(String[] args) {
ThreadB threadB1 = new ThreadB();
ThreadB threadB2 = new ThreadB();
ThreadB threadB3 = new ThreadB();
//
threadB1.start();
threadB2.start();
threadB3.start();
}
}
執行結果:
[email protected]
[email protected]
[email protected]
程式分析:
1、使用懶漢模式,三個執行緒取得是同一例項;
2、懶漢模式是靜態變數,但是沒有賦值,被呼叫時建立單例賦值給靜態變數;
3、懶漢模式如果不同步(synchronized),每次呼叫時會建立不同的例項,如果同步方法或者同步程式碼塊,效率都很低(排斥其他執行緒進入);
4、程式中使用了雙檢查鎖機制(DCL)實現多執行緒環境中延時載入單列設計模式。