前言:
這周忙的不行,沒學(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)再來聊聊。