前言
最近在做一個(gè)原始成績統(tǒng)計(jì)的功能,用戶通過前臺(tái)設(shè)置相關(guān)參數(shù),后臺(tái)實(shí)時(shí)統(tǒng)計(jì)并返回?cái)?shù)據(jù)。相對(duì)來說統(tǒng)計(jì)功能點(diǎn)還是比較多的,這里大體羅列一下。
- 個(gè)人排名
- 本次測試的優(yōu)良線、及格線、低分線
- 各個(gè)班級(jí)的排名人數(shù)(1-25、26-50 類比等等)
- 各個(gè)班級(jí)的前x名人數(shù)統(tǒng)計(jì)(前10、前20 類比等等)
- 各個(gè)班級(jí)的分?jǐn)?shù)段學(xué)生人數(shù)統(tǒng)計(jì)(150-140、139-130 類比等等)
最好的用戶體驗(yàn),就是每一個(gè)操作都可以實(shí)時(shí)的展示數(shù)據(jù),3秒之內(nèi)應(yīng)該是用戶的忍受范圍之內(nèi)的了,所以做一款產(chǎn)品不僅要考慮用戶交互設(shè)計(jì),后端的優(yōu)化也是比不可少的。
大家可以簡單的看下以上這5項(xiàng)統(tǒng)計(jì)數(shù)據(jù),總體來說,統(tǒng)計(jì)量還是不少的。最主要的還是要實(shí)時(shí)、實(shí)時(shí)、實(shí)時(shí)(重要的事情說三遍),顯然定時(shí)任務(wù)是不現(xiàn)實(shí)的。
改造前
程序邏輯
順序執(zhí)行任務(wù).png
改造后
程序邏輯
多任務(wù)并行處理.png
多任務(wù)并行處理,適用于多核cpu,單核cpu多線程執(zhí)行任務(wù)可能會(huì)適得其反(上下文切換以及線程的創(chuàng)建和銷毀都會(huì)消耗資源),特別是cpu密集型的任務(wù)。
代碼實(shí)現(xiàn)
statsdemo偽代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
/** * 多任務(wù)并行統(tǒng)計(jì) * 創(chuàng)建者 科幫網(wǎng) * 創(chuàng)建時(shí)間 2018年4月16日 */ public class statsdemo { final static simpledateformat sdf = new simpledateformat( "yyyy-mm-dd hh:mm:ss" ); final static string starttime = sdf.format( new date()); public static void main(string[] args) throws interruptedexception { countdownlatch latch = new countdownlatch( 5 ); // 兩個(gè)賽跑者 stats stats1 = new stats( "任務(wù)a" , 1000 , latch); stats stats2 = new stats( "任務(wù)b" , 2000 , latch); stats stats3 = new stats( "任務(wù)c" , 2000 , latch); stats stats4 = new stats( "任務(wù)d" , 2000 , latch); stats stats5 = new stats( "任務(wù)e" , 2000 , latch); stats1.start(); //任務(wù)a開始執(zhí)行 stats2.start(); //任務(wù)b開始執(zhí)行 stats3.start(); //任務(wù)c開始執(zhí)行 stats4.start(); //任務(wù)d開始執(zhí)行 stats5.start(); //任務(wù)e開始執(zhí)行 latch.await(); // 等待所有人任務(wù)結(jié)束 system.out.println( "所有的統(tǒng)計(jì)任務(wù)執(zhí)行完成:" + sdf.format( new date())); } static class stats extends thread { string statsname; int runtime; countdownlatch latch; public stats(string statsname, int runtime, countdownlatch latch) { this .statsname = statsname; this .runtime = runtime; this .latch = latch; } public void run() { try { system.out.println(statsname+ " do stats begin at " + starttime); //模擬任務(wù)執(zhí)行時(shí)間 thread.sleep(runtime); system.out.println(statsname + " do stats complete at " + sdf.format( new date())); latch.countdown(); //單次任務(wù)結(jié)束,計(jì)數(shù)器減一 } catch (interruptedexception e) { e.printstacktrace(); } } } } |
由于要同步返回統(tǒng)計(jì)數(shù)據(jù),這里我們使用到了countdownlatch類,它是java5中新增的一個(gè)并發(fā)工具類,其使用非常簡單,參考上面的偽代碼給出了詳細(xì)的使用步驟。
countdownlatch用于同步一個(gè)或多個(gè)任務(wù),強(qiáng)制他們等待由其他任務(wù)執(zhí)行的一組操作完成。countdownlatch典型的用法是將一個(gè)程序分為n個(gè)互相獨(dú)立的可解決任務(wù),并創(chuàng)建值為n的countdownlatch。當(dāng)每一個(gè)任務(wù)完成時(shí),都會(huì)在這個(gè)鎖存器上調(diào)用countdown,等待問題被解決的任務(wù)調(diào)用這個(gè)鎖存器的await,將他們自己攔住,直至鎖存器計(jì)數(shù)結(jié)束。
具體的源碼解讀,大家可以參考: 源碼分析之countdownlatch
項(xiàng)目源碼:https://gitee.com/52itstyle/spring-data-jpa
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.52itstyle.com/archives/2689/