前言
最近在做一个原始成绩统计的功能,用户通过前台设置相关参数,后台实时统计并返回数据。相对来说统计功能点还是比较多的,这里大体罗列一下。
- 个人排名
- 本次测试的优良线、及格线、低分线
- 各个班级的排名人数(1-25、26-50 类比等等)
- 各个班级的前x名人数统计(前10、前20 类比等等)
- 各个班级的分数段学生人数统计(150-140、139-130 类比等等)
最好的用户体验,就是每一个操作都可以实时的展示数据,3秒之内应该是用户的忍受范围之内的了,所以做一款产品不仅要考虑用户交互设计,后端的优化也是比不可少的。
大家可以简单的看下以上这5项统计数据,总体来说,统计量还是不少的。最主要的还是要实时、实时、实时(重要的事情说三遍),显然定时任务是不现实的。
改造前
程序逻辑
顺序执行任务.png
改造后
程序逻辑
多任务并行处理.png
多任务并行处理,适用于多核cpu,单核cpu多线程执行任务可能会适得其反(上下文切换以及线程的创建和销毁都会消耗资源),特别是cpu密集型的任务。
代码实现
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
|
/**
* 多任务并行统计
* 创建者 科帮网
* 创建时间 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 ); // 两个赛跑者
stats stats1 = new stats( "任务a" , 1000 , latch);
stats stats2 = new stats( "任务b" , 2000 , latch);
stats stats3 = new stats( "任务c" , 2000 , latch);
stats stats4 = new stats( "任务d" , 2000 , latch);
stats stats5 = new stats( "任务e" , 2000 , latch);
stats1.start(); //任务a开始执行
stats2.start(); //任务b开始执行
stats3.start(); //任务c开始执行
stats4.start(); //任务d开始执行
stats5.start(); //任务e开始执行
latch.await(); // 等待所有人任务结束
system.out.println( "所有的统计任务执行完成:" + 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);
//模拟任务执行时间
thread.sleep(runtime);
system.out.println(statsname + " do stats complete at " + sdf.format( new date()));
latch.countdown(); //单次任务结束,计数器减一
} catch (interruptedexception e) {
e.printstacktrace();
}
}
}
}
|
由于要同步返回统计数据,这里我们使用到了countdownlatch类,它是java5中新增的一个并发工具类,其使用非常简单,参考上面的伪代码给出了详细的使用步骤。
countdownlatch用于同步一个或多个任务,强制他们等待由其他任务执行的一组操作完成。countdownlatch典型的用法是将一个程序分为n个互相独立的可解决任务,并创建值为n的countdownlatch。当每一个任务完成时,都会在这个锁存器上调用countdown,等待问题被解决的任务调用这个锁存器的await,将他们自己拦住,直至锁存器计数结束。
具体的源码解读,大家可以参考: 源码分析之countdownlatch
项目源码:https://gitee.com/52itstyle/spring-data-jpa
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.52itstyle.com/archives/2689/