單例的理解
hi, 大家好,我是愛吃香蕉的猴子,今天看到郭神之前的一篇文章膜拜,關于使用單例的,自己有些感觸,就借鑒寫一下記錄.
延續大神的例子:
第一版
不使用單例,new的太多,占用記憶體,不可取;
第二版
public class LogUtil {
private static LogUtil sLogUtil;
public static LogUtil getInstance() {
//1
if (sLogUtil == null) { //2
//3
sLogUtil = new LogUtil(); //4
}
/ /5
return sLogUtil;
}
}
LogUtil.getInstance().debug("Hello World");
這種方式,如果在多執行緒模式下,如果thead B、thread A, 在3位置 這樣,thread A初始化了,thread B也會初始化,這樣也會出現兩個實體,則需要增加鎖,
第三版
private static LogUtil sLogUtil;
public synchronized static LogUtil getInstance() {
if (sLogUtil == null) {
sLogUtil = new LogUtil();
}
return sLogUtil;
}
在方法上加上synchronized,執行緒排隊執行,每次執行getInstance都要受鎖影響,這樣效率相對低一些;
第四版
private static LogUtil sLogUtil;
public static LogUtil getInstance() {
synchronized (LogUtil.class) {
if (sLogUtil == null) {
sLogUtil = new LogUtil();
}
return sLogUtil;
}
}```
在方法內增加類鎖,但是:如果theadA threadB都在鎖外,已經初始化的也在排隊,是否可以增加判斷;
*第五版*
private static LogUtil sLogUtil;
public static LogUtil getInstance() {
if (sLogUtil == null) {
//沒有初始化的排隊
synchronized (LogUtil.class) {
if (sLogUtil == null) {
sLogUtil = new LogUtil();
}
}
}
return sLogUtil;
這樣,代碼改成這樣之后,基本完善了,但是在執行緒A中sLogUtil實體化了,在執行緒B中是可見的嗎?
第六版
private volatile static LogUtil sLogUtil;
public static LogUtil getInstance() {
/ /0
if (sLogUtil == null) { // 1
//2
synchronized (LogUtil.class) { // 3
//4
if (sLogUtil == null) { // 5
//6
sLogUtil = new LogUtil(); //7
}
}
}
return sLogUtil;
}
增加了Volatile [?v?l?ta?l] ,這樣執行緒間可見;
這樣,算是完整了,
有人問我,為什么5還要加一次判斷?
我是這樣認為的,在ThreadA 執行了7,這個時候,TheadB執行到3進入4,這種場景,自然就需要增加一次判斷;
還有人提出過,為什么不用列舉,這個方案雖然是java里面被推薦的,但 個人認為不適合android, 因為列舉還是站用記憶體較大的,
為什么列舉占記憶體大
Code的搬運工V1.o
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/244700.html
標籤:其他
