JAVA學(xué)習(xí)筆記(三)

前言:

這周忙的不行,沒學(xué)多少東西,就簡單的學(xué)習(xí)下Java的單例吧。

設(shè)計(jì)模式之單例

單例模式是最簡單也是最常用的設(shè)計(jì)模式,在學(xué)習(xí)OC的過程中第一個(gè)接觸的設(shè)計(jì)模式就是單例,所以從單例入手來了解Java的一些特性也是極好的。

1.懶漢式單例

public class JMSingleManager {
    private JMSingleManager() {}
    private static JMSingleManager instance = null;
    //類方法
    public static JMSingleManager shareInstance() {
        if (instance == null) {
            instance = new JMSingleManager();
        }
        return instance;
    }
}

1.為了實(shí)現(xiàn)在整個(gè)軟件的生命周期內(nèi)這個(gè)類只能存在唯一一個(gè)實(shí)例,我們必須把Java默認(rèn)提供的構(gòu)造器私有化,這樣在外部就不能new一個(gè)對(duì)象了。
2.置于為什么要用類方法去實(shí)現(xiàn)單例,是因?yàn)轭惐仨殞?shí)例化一個(gè)類之后才能調(diào)用實(shí)例方法,總不能為了得到單例每次都要重新new一個(gè)對(duì)象吧,這樣寫十分怪異,并且性能也很差。
3.由于類方法只能訪問類中的靜態(tài)成員變量,所以該對(duì)象的定義也必須聲明為static。

我們發(fā)現(xiàn)Java的單例寫法和OC中的寫法基本一致,但是很容易發(fā)現(xiàn)的一個(gè)問題就是這種創(chuàng)建方式是線程不安全的,多個(gè)線程同時(shí)訪問可能會(huì)實(shí)例化多次,所以我們必須加上線程鎖,就像在OC中使用dispatch_once一樣,但是最常用的還是synchronized這個(gè)方法,在Java中也有synchronized,在使用上也和OC非常相像,我們把代碼改成下面這樣:

public static JMSingleManager shareInstance() {  
    if (instance == null) {    
        synchronized(JMSingleManager.class){
           instance = new JMSingleManager();  
        }
    }    
    return instance;  
}

在這里我們用synchronized修飾JMSingleManager這個(gè)類,類的所有對(duì)象共用一個(gè)鎖,synchronized不僅可以用來修飾,還能修飾指定的對(duì)象,也可以修飾實(shí)例方法、類方法,而且也可以修飾一個(gè)代碼塊,比如上述的代碼可以改成下面這樣:

public static synchronized JMSingleManager shareInstance() {  
     if (instance == null) {    
         instance = new JMSingleManager();  
     }    
     return instance;  
}

這里還有一種寫法,需要借助Java的關(guān)鍵字final

final:被final修飾的類無法被繼承,被final修飾的方法無法被重寫,被final修飾的變量只能被初始化一次,這里我們就要用這個(gè)特性,而且被final修飾的變量是天然線程安全的(因?yàn)橹荒艹跏蓟淮伟。。?/p>

所以單例我們可以這樣寫:

public class JMSingleManager {    
    private static class LazyHolder {    
       private static final JMSingleManager instance = new JMSingleManager();    
    }    
    private JMSingleManager (){}    
    public static final JMSingleManager shareInstance() {    
       return LazyHolder.instance;    
    }    
}    

2.餓漢式單例

public class JMSingleManager {    
    private JMSingleManager (){}    
    private static JMSingleManager instance = new JMSingleManager(); 
    public static JMSingleManager shareInstance() {    
       return instance;    
    }    
}  

這里主要通過Java的類加載機(jī)制來規(guī)避線程不安全的風(fēng)險(xiǎn),也是最簡單與最方便的寫法。
關(guān)于Java的類加載機(jī)制個(gè)人現(xiàn)在了解的還十分淺薄,以后等了解深一點(diǎn)再來聊聊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容