SSH框架網(wǎng)上商城項目第15戰(zhàn)之線程、定時器同步首頁數(shù)據(jù)
上一節(jié)我們做完了首頁UI界面,但是有個問題:如果我在后臺添加了一個商品,那么我必須重啟一下服務器才能重新同步后臺數(shù)據(jù),然后刷新首頁才能同步數(shù)據(jù)。這明顯不是我們想要的效果,一般這種網(wǎng)上商城首頁肯定不是人為手動同步數(shù)據(jù)的,那么如何解決呢?我們需要用到線程和定時器來定時自動同步首頁數(shù)據(jù)。
1. Timer和TimerTask
我們需要用到Timer和TimerTask兩個類。先來介紹下這兩個類。
Timer是一種工具類,在java.util包中,線程用其安排以后在后臺線程中執(zhí)行的任務。可安排任務執(zhí)行一次,或者定期重復執(zhí)行。它有個構(gòu)造函數(shù):
Timer(boolean isDaemon) //創(chuàng)建一個新計時器,可以指定其相關(guān)的線程作為守護程序運行。
守護線程即主線程結(jié)束后,該線程也結(jié)束,非守護線程即主線程結(jié)束后,該線程仍然繼續(xù)執(zhí)行。isDaemon為true時為守護線程。Timer類有個schedule方法可以創(chuàng)建一個任務,如下:
void schedule(TimerTask task, Date firstTime, long period) //安排指定的任務在指定的時間開始進行重復的固定延遲執(zhí)行。 //第一個參數(shù)是指定任務,即TimerTask對象;第二個參數(shù)為第一次開啟任務時間; 第三個參數(shù)為時間間隔,即每隔多長時間執(zhí)行一次
我們再來看看TimerTask,TimerTask是用來創(chuàng)建一個新的線程任務的,它實現(xiàn)了Runnable接口,如果我們要創(chuàng)建一個新的線程任務,只需要繼承TimerTask,并重寫run方法即可。
2. 創(chuàng)建一個新的線程任務
下面我們來創(chuàng)建一個新的線程任務,用來更新后臺數(shù)據(jù):
@Component //把該對象交給Spring管理
public class ProductTimerTask extends TimerTask {
@Resource
private ProductService productService = null; //注入productService
@Resource
private CategoryService categoryService = null; //注入categoryService
private ServletContext application = null; //定義一個ServletContext對象,因為我們更新了后臺數(shù)據(jù)后,需要存入application域里面
public void setApplication(ServletContext application) {
this.application = application; //通過監(jiān)聽器將這個application對象set進來,因為這里是無法拿application對象的
}
@Override
//和監(jiān)聽器在項目啟動的時候數(shù)據(jù)初始化的邏輯一樣
public void run() {
System.out.println("----run----");
List<List<Product>> bigList = new ArrayList<List<Product>>(); //bigList中存放一個裝有Category類的list
// 1. 查詢出熱點類別
for(Category category : categoryService.queryByHot(true)) {
//根據(jù)熱點類別id獲取推薦商品信息
List<Product> lst = productService.querByCategoryId(category.getId());
bigList.add(lst); //將裝有category的list放到bigList中
}
// 2. 把查詢的bigList交給application內(nèi)置對象
application.setAttribute("bigList", bigList); //假設我們已經(jīng)拿到了application對象
}
}
接下來,我們修改項目啟動時監(jiān)聽器里面的內(nèi)容,原本上面的這個查詢操作是放在監(jiān)聽器中,當項目啟動時,監(jiān)聽器開始執(zhí)行,獲取后臺數(shù)據(jù),存到application域中,然后前臺通過jstl標簽從application域中拿到數(shù)據(jù)?,F(xiàn)在我們把這些事情交給我們定義的ProductTimerTask去做,那么監(jiān)聽器中只要設置一下定時器,讓ProductTimerTask定時去更新一下后臺數(shù)據(jù)即可??纯幢O(jiān)聽器中修改后的代碼:
3. 在監(jiān)聽器中啟動定時器
//@Component //監(jiān)聽器是web層的組件,它是tomcat實例化的,不是Spring實例化的。不能放到Spring中
public class InitDataListener implements ServletContextListener {
private ProductTimerTask productTimerTask = null; //定義一個ProductTimerTask對象
private ApplicationContext context = null;
@Override
public void contextDestroyed(ServletContextEvent event) {
// TODO Auto-generated method stub
}
@Override
public void contextInitialized(ServletContextEvent event) {
context = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
productTimerTask = (ProductTimerTask) context.getBean("productTimerTask");//從配置文件中獲取ProductTimerTask對象
//把內(nèi)置對象交給productTimerTask,因為productTimerTask里面是拿不到application的,只能通過監(jiān)聽器set給它
productTimerTask.setApplication(event.getServletContext());
//通過設置定時器,讓首頁的數(shù)據(jù)每個一小時同步一次(配置為守護線程)
new Timer(true).schedule(productTimerTask, 0, 1000*60*60);//每個一小時執(zhí)行一次productTimerTask任務,即更新一下后臺數(shù)據(jù)
}
}
關(guān)于InitDataListener監(jiān)聽器中原來的操作代碼,可以對比上一節(jié)中的內(nèi)容,其實就是ProductTimerTask中的更新后臺數(shù)據(jù),只不過現(xiàn)在放到TimerTask中去做了而已。這樣我們就完成了使用線程和定時器定期同步首頁數(shù)據(jù),這個時間間隔可以自己設定。
其實CSDN博客里的部分首頁數(shù)據(jù)也不是實時更新的,每天晚上會有個時間更新一次,例如左側(cè)欄目中的博客排名,閱讀排行后的顯示的閱讀量等,這些都是每天晚上更新一次,應該就是在后臺設置了每天更新一次,原理跟這里應該是一樣的。這樣也減輕了服務器的壓力。
本文鏈接:http://blog.csdn.net/eson_15/article/details/51387378
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Java郵件發(fā)送程序(可以同時發(fā)給多個地址、可以帶附件)
- java 發(fā)送郵件的實例代碼(可移植)
- java發(fā)送郵件的具體實現(xiàn)
- java mail使用qq郵箱發(fā)郵件的配置方法
- Java Mail與Apache Mail發(fā)送郵件示例
- java中javamail發(fā)送帶附件的郵件實現(xiàn)方法
- Java讀取郵件的方法
- SSH框架網(wǎng)上商城項目第12戰(zhàn)之添加和更新商品功能
- SSH框架網(wǎng)上商城項目第17戰(zhàn)之購物車基本功能
- SSH框架網(wǎng)上商城項目第25戰(zhàn)之使用java email給用戶發(fā)送郵件
相關(guān)文章
Java實現(xiàn)優(yōu)雅停止線程的有效方法詳解
這篇文章主要為大家詳細如何安全有效停止 Java 線程的,確保多線程應用程序平穩(wěn)運行并實現(xiàn)最佳資源管理,感興趣的小伙伴可以跟隨小編一起學習一下2023-12-12
Spring?Security如何實現(xiàn)升級密碼加密方式詳解
這篇文章主要為大家介紹了Spring?Security實現(xiàn)升級密碼加密方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01
Javabean基于xstream包實現(xiàn)轉(zhuǎn)XML文檔的方法
這篇文章主要介紹了Javabean基于xstream包實現(xiàn)轉(zhuǎn)XML文檔的方法,結(jié)合具體實例形式分析了xstream包用于轉(zhuǎn)換xml文件的具體使用技巧,需要的朋友可以參考下2017-05-05
解決SpringMVC @RequestMapping不設置value出現(xiàn)的問題
這篇文章主要介紹了解決SpringMVC @RequestMapping不設置value出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
在Spring Boot中使用Spring-data-jpa實現(xiàn)分頁查詢
如何使用jpa進行多條件查詢以及查詢列表分頁呢?下面我將介紹兩種多條件查詢方式。具體實例代碼大家參考下本文吧2017-07-07

