很多學j2ee方向的同學都接觸過s2sh,即傳統的三大框架,學習這三個經典技術的重點就是挖原理和細節,慢慢地我們就能形成一套思想,以幫助理解其他新框架和新技術。學習技術本身並不難,設計技術方案才是難點,為什麼要這麼設計,這樣設計的哲學依據又在哪?
不難發現:struts2中控制層的action是多例的,在action層一般引用了邏輯層的單例service,而在邏輯層中又引用了單例的dao。因為作為控制層,action必須接受前端傳遞的引數,而struts2又基於***思想,建立http請求後要經由複雜的***才能到達控制層進行處理。這些引數就是action中的成員變數,如果併發請求action而action又是單例的,這不是會發生非執行緒安全麼?而service頂多就只有dao的引用作為成員變數,dao本身也只有對運算元據庫的包裝類的引用充當成員變數,所以沒有涉及到非執行緒安全,即本身就是執行緒安全。所以我們spring框架在預設情況下的bean都是單例模式。每一次訪問方法進行處理都要new物件和**物件,浪費系統資源,而單例模式就是可以解決這個問題。以下的實驗是在網路環境不怎麼好的情況下進行的,把時長拉得更加明顯。
非單例模式的情況:
controller層(jersey框架,基於rest風格的web service)
@get
@path("history_station_user")
public string gethistorystationuserinfo(
@queryparam("area_list") @defaultvalue("null") string arealist,
@queryparam("year_month") @defaultvalue("null") string yearmonth)
string area = arealist.split(",");
userservice userservice = new userserviceimpl();//非單例
list list = userservice.gethistorystationuserlist(yearmonth, area);
return jsonutil.getdataresponse(status.ok, list).tostring();
}
service層(每次都new乙個物件):
public
class
userserviceimpl
implements
userservice
該專案放在某外網中的區域網,通過埠對映到外網才可訪問,所以接受速度有點慢。
(可右鍵「在新標籤頁中開啟」)
我們可以看到,返回400kb左右的json資料。
第一次訪問月份為2時,用時12.27s;controller層(jersey框架,基於rest風格的web service)第一次訪問月份為3時,用時6.82s;
第一次訪問月份為4時,用時4.86s;
第二次訪問月份為2時,用時1.31s;(第二次從二級快取中讀取)
第二次訪問月份為3時,用時868ms;
第二次訪問月份為4時,用時775ms。
@get
@path("history_station_user")
public string gethistorystationuserinfo(
@queryparam("area_list") @defaultvalue("null") string arealist,
@queryparam("year_month") @defaultvalue("null") string yearmonth)
string area = arealist.split(",");
userservice userservice = userserviceimpl.getinstance();//單例
list list = userservice.gethistorystationuserlist(yearmonth, area);
return jsonutil.getdataresponse(status.ok, list).tostring();
}
service層(懶漢雙重鎖定單例模式):
public
class
userserviceimpl
implements
userservice }}
return instance;
}private
userserviceimpl()
...}
(可右鍵「在新標籤頁中開啟」)
我們可以看到,返回400kb左右的json資料。
第一次訪問月份為2時,用時9.32s;service層(餓漢單例模式):第一次訪問月份為3時,用時5.89s;
第一次訪問月份為4時,用時4.78s;
第二次訪問月份為2時,用時1.03s;(第二次從二級快取中讀取)
第二次訪問月份為3時,用時1.12s;
第二次訪問月份為4時,用時748ms。
public
class
userserviceimpl
implements
userservice
/*** 靜態工廠方法
*/public
static userserviceimpl getinstance()
...}
(可右鍵「在新標籤頁中開啟」)
我們可以看到,返回400kb左右的json資料。
第一次訪問月份為2時,用時5.46s;經過三種方式的對比,我們發現經過二級快取的效能優化後,採用的這三種策略也對效能的響應有影響,採用餓漢單例模式可以良好地提高響應速度。第一次訪問月份為3時,用時4.19s;
第一次訪問月份為4時,用時3.14s;
第二次訪問月份為2時,用時329ms;(第二次從二級快取中讀取)
第二次訪問月份為3時,用時291ms;
第二次訪問月份為4時,用時298ms。
@nanphonfy
email:nanphonfy (nfzone) gmail.com 請將(nfzone)換成@
controller層和service層的作用
1.在controller和service裡都寫那些 controller,從字面上理解是控制器,所以它是負責業務排程的,所以在這一層應寫一些業務的排程 而具體的業務處理應放在service中去寫,而且service不單純是對於dao的增刪改查的呼叫,service是業務層,所以應該更切近於具體業務...
Django 資料層效能優化
django資料層提供各種途徑優化資料的訪問,乙個專案大量優化工作一般是放在後期來做,早期的優化是 萬惡之源 這是前人總結的經驗,不無道理。如果事先理解django的優化技巧,開發過程中稍稍留意,後期會省不少的工作量。一 利用標準資料庫優化技術 傳統資料庫優化技術博大精深,不同的資料庫有不同的優化技...
效能優化 合成層
1.提公升移動或漸變元素的繪製層 繪製並非總是在記憶體中的單層畫面裡完成的。實際上,瀏覽器在必要時將會把一幀畫面繪製成多層畫面,然後將這若干層畫面合併成一張顯示到螢幕上。通過渲染層提公升可以減小繪製區域,我們可以用除錯工具檢視到繪製層 在頁面中新建乙個渲染層最好的方式就是使用 will change...