Java知識點總結業務場景篇6-10

六、Ajax請求Session超時問題

我在做項目時有時會遇到session超時問題,如果session超時,平常請求沒有什么問題,通過攔截器可以正確跳到登陸頁面,可是你如果用ajax請求的話這就出現問題了,因為ajax是異步的,局部刷新,所以登陸界面不會再全頁面中顯示,他只會顯示到頁面的一部分當中。所以根據我這幾年的經驗找到了我認為比較好的一種方法。因為那我用的框架是和struts2集成的,所以就在攔截器中進行設置:

首先判斷session是否為空就是判斷session是否超時,如果超時就取出請求的head頭信息request.getHeader("x-requested-with"),如果不為空就和XMLHttpRequest(Ajax標識)進行比較 (request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest"))) 如果相等說明此請求是ajax請求。

如果是ajax請求就可以用response.setHeader("鍵","值")來設置一個標識來告訴用戶這是ajax請求并且session超時時發出的,這樣我就可以在回調函數中取出自己設置的那個唯一標識:XMLHttpRequest.getResponseHeader("");如果取出的值是和自己在后臺中設置的值一樣的話,就證明session已經超時,這樣就可以設置window.location.replace("登陸界面"),來跳轉到登陸界面了。

這樣做雖然解決了問題,但是,會在每個回調函數中寫入那些代碼,這樣的話代碼就會顯得特別零散,所以就想能不能定義一個全局的設置所以就找到了jqery的ajaxSetUp方法,通過ajaxSetUp對jqery的ajax進行全局的判斷(ajaxSetUp就相當于ajax的攔截器),通過設置ajaxSetUp里的complete,它就相當于回調函數,這樣那就彌補了上一方法的不足。

我做項目時還用到$(document).ajaxStart(),這是ajax請求時的事件;$(document).ajaxSuccess(),這是AJAX請求成功后的事件。我一般用他們來顯示遮罩層和隱藏遮罩層用的加遮罩層是為了不讓用戶重復提交,更提高了用戶體驗度,讓用戶知道已經提交了。

七、java線程池概述

java線程池的工作原理和數據庫連接池的差不多,因為每次重新創建線程

都是很耗資源的操作,所以我們可以建立一個線程池,這樣當需要用到線程

進行某些操作時,就可以直接去線程池里面找到空閑的線程,這樣就可以直接

使用,而不用等到用到的時候再去創建,用完之后可以把該線程重新放入線程池

供其他請求使用從而提高應用程序的性能。

線程池的核心流程:

1.構建一個 ThreadPoolExecutor 并指定默認要創建的線程的數量

2.通過 threadPool.execute()

去添加一個個要執行的線程即實現了Runable接口的java類

3.在實現了Runable接口的java類的run方法中寫入具體的業務代碼

線程池的業務場景:

我在工作的時候,當時一個同事給我提了一個需求,目前有大量的圖片

需要處理生產縮略圖并進行加水印,因為按照普通的處理方法一個個的

進行處理太慢了,問我有沒有好的解決方案,這個時候我就想到了java中

的線程池,我構建了一個線程數為5個線程池,然后采用分段批量提取的

方式每500條為一組數據進行圖片信息的提取,然后再把這些通過Threadpool的

execute方法交給線程池中的線程進行處理,即充分使用了CPU硬件資源又加快

了大數據情況下程序的處理效率。

我當時在工作的過程中,認識一個做電商的朋友,他們當時公司才起步,很多

技術都不成熟,所以就常常和我探討一些技術問題,有次他向我請教一個問題,

問我如何才能提高網站的性能,我根據自己在項目中的經驗以及自己以前閱讀的

關于優化方面的資料給他提出了很多建議,如用lucene進行全文檢索,用memcached

進行分布式緩存,以及通過spring定時器結合freeMarker模板引擎來生成靜態

頁面,由于要生成的頁面的數量比較多,考慮到程序的性能,我建議他結合

java的線程池進行工作,這樣就可以充分使用了CPU硬件資源又加快

了大數據情況下程序的處理效率。

八、OSCache概述

oscache是一個高性能的j2ee框架,可以和任何java代碼進行集成,并且還可以通過標簽對頁面內容進行緩存,還以緩存請求。

我們通常將那些頻繁訪問但是又不是經常改變的數據進行緩存。為了保證緩存數據的有效性,在數據發生改變的時候,我們要刷新緩存,避免臟數據的出現。刷新緩存的策略有兩種,一種是定時刷新,一種手動刷新。

緩存數據的時機通常也分為兩種,即在tomcat(web容器)啟動時候加載數據進行緩存,另外也可以在用戶第一次訪問數據的時候進行緩存,這個相當于緩存的立即加載和按需加載。

緩存的層次如下:jsp-->action-->service-->dao,緩存越靠前對性能的提升越大

一個action里面可以有多個service,一個service中可以有多個dao或者多個service

任何類之間都可以進行相互調用,可以通過構造函數傳參,set,get傳參或者是方法傳 參將相關的類連接起來。

九、OSCache+autocomplete+單例業務場景

在我以前做某項目的過程中,其中我們在做產品列表的查詢的時候為了提高用戶的體驗度,我們使用了autocomplete插件來代替select進行品牌的選擇,才開始的時候每次都要根據用戶輸入的信息去查詢數據庫進行模糊匹配返回結果,后來我們考慮到系統的性能,因此我們采用了oscache緩存,才開始這個功能是交給我們項目組中的另外一個同事來做的,但是他做完后,我們在使用這個工具類的時候,發現有時緩存中明明已經有時我們需要的數據,但是從緩存里面取的時候,發現沒有,之后項目經理讓我去幫這個同事看看這個問題,我經過閱讀他的代碼發現,它里面在使用緩存的時候,針對于每次方法的調用都產生一個新的實例,結果導致了上面的問題,這個時候我想起了可以使用設計模式中的單例模式來解決這個問題,才開始我直接采用了普通的單列模式,但是后來在測試的過程中,發現當用戶并發量大的時候還是會出現上面的問題,之后我再次考慮了代碼,最后發現是因為沒有給單列模式加鎖的原因,從而導致了大用戶并發的時候,線程安全的問題,之后我便在方法上加上了synchronized關鍵字,解決上述的問題,但是后來測試人員反饋,覺的這段的性能有問題,我考慮之后便采用在方法體內加鎖并結合雙重判定的方式解決了上面的問題。我們是將數據在tomcat啟動的時候加載到緩存中,之后用戶進行查詢的時候直接從緩存中獲取數據,根據前綴匹配進行查詢,將結果返回給用戶。這樣在提高用戶體驗度的同時也提高性能。

十、緩存概述

應用程序為了提高性能,可以通過使用緩存來達到目的,緩存的存儲介質可以

內存或者硬盤,通常將數據存儲在內存里,確切的說是jvm的內存中,緩存是

基于Map這種思想構建的,以鍵值對的方式進行存取,之所以還可以將

緩存的數據存儲在硬盤中,是因為內存資源相當有限和寶貴,所以當內存資源

不足的時候,就可以將其存儲到硬盤中,雖然硬盤的存取速度比內存要慢,但是

因為減少了網絡通信量,所以還是提高程序的性能。緩存可以分為客戶端緩存和

服務器端緩存,所謂的客戶端緩存通常指的是IE瀏覽器的緩存,服務器端緩存指

的web服務器的緩存,通常可以通過第三方組件實現,如oscache,memcache

我們通常將那些頻繁訪問但是又不是經常改變的數據進行緩存。為了保證緩存數據的

有效性,在數據發生改變的時候,我們要刷新緩存,避免臟數據的出現。刷新緩存的

策略有兩種,一種是定時刷新,一種手動刷新。

緩存的層次如下:jsp-->action-->service(通常放置在service)-->dao,

緩存越靠前對性能的提升越大

緩存的策略:(緩存空間不足需要進行清理的時候使用)

LRU:最近最少使用原則.(理解:存儲書)

FIFO:先進先出的緩存策略.(理解:排隊)

你來說說緩存?說說你對緩存的理解(如果遇到重復的,就可以省略)

我們在項目中使用緩存的目的是為了提高應用程序的性能,減少訪問數據庫

的次數,從而提高應用程序的吞吐量。我們通常將權限,菜單,組織機構

這些頻繁訪問但是不經常改變的基礎數據進行緩存,其中我在做()某某項目的時候

就通過oscache對ZTree的樹形菜單進行了緩存,并且在做的時候和單列設計

模式進行結合,考慮到多線程下的安全問題,還對單例模式加入了雙重判定鎖

的檢查方式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容