這篇文章主要介紹“java單例模式實(shí)例分析”,在日常操作中,相信很多人在java單例模式實(shí)例分析問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”java單例模式實(shí)例分析”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
十余年的志丹網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營(yíng)銷型網(wǎng)站的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整志丹建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“志丹網(wǎng)站設(shè)計(jì)”,“志丹網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
在早期的項(xiàng)目代碼中,如果我們想使用類的某個(gè)方法,我們基本都會(huì)創(chuàng)建一個(gè)類的對(duì)象實(shí)例然后再調(diào)用方法,這樣的實(shí)現(xiàn)往往在系統(tǒng)內(nèi)就會(huì)存在某個(gè)類的大量實(shí)例。如此一來(lái),項(xiàng)目框架很難管理大量的對(duì)象,而且如果java虛擬機(jī)不能及時(shí)回收,容易造成內(nèi)存溢出。
首先我們要明白什么是單例,所謂單例就是說(shuō)在項(xiàng)目框架內(nèi)某個(gè)類的對(duì)象實(shí)例只存在一個(gè),任何調(diào)用方獲取到的對(duì)象實(shí)例都是一個(gè),那么很明顯這個(gè)類是不能夠被外部直接調(diào)用類構(gòu)造器創(chuàng)建的。
我們先看下一個(gè)簡(jiǎn)單的單例設(shè)計(jì):
上面代碼在單線程是沒(méi)有問(wèn)題的,而且只有當(dāng)線程調(diào)用類的靜態(tài)方法時(shí),才會(huì)生成類的靜態(tài)變量。但是當(dāng)多線程訪問(wèn)時(shí),上面代碼是有問(wèn)題的,會(huì)生成多個(gè)對(duì)象的實(shí)例。
那么,我們可以用另外一種方法實(shí)現(xiàn),比如說(shuō)在類加載時(shí)候就初始化對(duì)象的實(shí)例,這樣后面無(wú)論怎么調(diào)用類靜態(tài)方法都不創(chuàng)建新的實(shí)例。還有一種方法,但是會(huì)犧牲部分系統(tǒng)性能,意思就是在多線程訪問(wèn)方法時(shí)通過(guò)鎖機(jī)制讓線程排隊(duì)訪問(wèn)。我們先通過(guò)在類方法上加鎖來(lái)實(shí)現(xiàn)類的單例,比如:
上述方法能實(shí)現(xiàn)單例,而且采用的思路是延遲加載,但是執(zhí)行效率比較低。
之前有看到部分同學(xué)使用雙重鎖(Double CheckLock)機(jī)制來(lái)實(shí)現(xiàn)單例模式,一方面需要在實(shí)例上加上volatile關(guān)鍵字通知操作系統(tǒng)實(shí)現(xiàn)線程訪問(wèn)時(shí)內(nèi)存屏障,然后還需要在方法中通過(guò)虛擬機(jī)實(shí)現(xiàn)的synchronized來(lái)同步方法訪問(wèn),寫(xiě)法如下:
反正,我認(rèn)為上面的實(shí)現(xiàn)是比較復(fù)雜的,大家需要去了解的知識(shí)點(diǎn)比較多,比如volatile ,synchronized,內(nèi)存屏障。因此我不建議大家用這種方式,可以作為技術(shù)了解下還是有好處的,畢竟如果能跟面試官探討到這一步,還是會(huì)加一些分的。
如果說(shuō)我們不考慮服務(wù)負(fù)載問(wèn)題,在多線程環(huán)境下可以預(yù)先加載類的靜態(tài)實(shí)例,當(dāng)虛擬機(jī)加載完成類后就會(huì)創(chuàng)建類的靜態(tài)變量,甭管你到時(shí)用不用,反正給你留在那里。所有線程訪問(wèn)到的都是同一靜態(tài)實(shí)例,有人也稱這種方式為餓漢式,具體寫(xiě)法如下:
上面寫(xiě)法實(shí)現(xiàn)單例也是沒(méi)有問(wèn)題的,但是有些同學(xué)就會(huì)覺(jué)得如果我只是想調(diào)用一個(gè)類的某個(gè)靜態(tài)方法,并不想生成它的實(shí)例,那有沒(méi)有其他方法呢,經(jīng)過(guò)各路大神的指點(diǎn)結(jié)合自身的總結(jié),可以使用內(nèi)部靜態(tài)類來(lái)實(shí)現(xiàn)這個(gè)需求。
開(kāi)發(fā)的同學(xué)都知道,虛擬機(jī)在加載類的過(guò)程中一開(kāi)始并不會(huì)初始化類的內(nèi)部靜態(tài)類。如果線程調(diào)用內(nèi)部靜態(tài)類時(shí),虛擬機(jī)只會(huì)初始化一次,這樣既可以實(shí)現(xiàn)單例,同時(shí)也是線程安全的。具體寫(xiě)法如下:
除了以上講到的幾種方式外,JDK自身的枚舉類型本身就是單例的實(shí)現(xiàn),調(diào)用者不能顯式的調(diào)用構(gòu)造器完成實(shí)例創(chuàng)建,因此很多Java規(guī)范文檔推薦使用枚舉來(lái)實(shí)現(xiàn)單例。
當(dāng)然對(duì)于初級(jí)開(kāi)發(fā)人員而言,現(xiàn)在的主流開(kāi)發(fā)框架都提供單例/多例模式供開(kāi)發(fā)者選擇,這樣的好處讓開(kāi)發(fā)者更多關(guān)注業(yè)務(wù)功能開(kāi)發(fā),而不用過(guò)多關(guān)注虛擬機(jī)內(nèi)部類實(shí)例創(chuàng)建問(wèn)題。例如spring中默認(rèn)類注入就是單例的,可以根據(jù)實(shí)際情況設(shè)置scope為singleton(單例)或者prototype(多例),如下圖所示:
到此,關(guān)于“java單例模式實(shí)例分析”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
文章名稱:java單例模式實(shí)例分析
本文來(lái)源:http://aaarwkj.com/article26/ipoojg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站設(shè)計(jì)公司、外貿(mào)建站、App開(kāi)發(fā)、Google、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)