您的当前位置:首页正文

多线程统计次数问题:即count++

2022-09-15 来源:步旅网
多线程统计次数问题:即count++

场景:⽇志需要统计每天数据上传的次数和上传的数据量。

如果是单线程可以使⽤简单的int count = 0;count++,但很多情况都是多线程环境所以就不能单纯的使⽤count++了!!!

多线程环境采⽤ java.util.concurrent.atomic 下的AtomicLong类,该类的介绍可看API⽂档。可以⽤原⼦⽅式更新的 long 值。有关原⼦变量属性的描述,请参阅 包规范。AtomicLong 可⽤在应⽤程序中(如以原⼦⽅式增加的序列号),并且不能⽤于替换 。但是,此类确实扩展了Number,允许那些处理基于数字类的⼯具和实⽤⼯具进⾏统⼀访问。每天都要把统计的次数置为0,可以使⽤定时器,每天零点零分将次数重置为0,该⽅法不易拓展;另⼀种⽅法是使⽤全局变量时间戳,判断当前⽇期是不是与时间戳相等,如果是就说明今天的次数累加;如果不是就要把时间戳重置为当天的⽇期,并把次数重置为0。多线程情况下采⽤锁加double check⽅法确保解决并发问题!

1 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(\"yyyy-MM-dd\"); 2 3 /**

4 * 获得当前⽇期 5 *

6 * ⽇期格式yyyy-MM-dd 7 *

8 * @return 9 */

10 public static String currentDate() {

11 return DATE_FORMAT.format(new Date());12 }

1 //上传次数

2 private final AtomicLong count = new AtomicLong(0); 3

4 //上传数据量

5 private final AtomicLong dataSize = new AtomicLong(0); 6

7 //时间戳

8 private String today = DateUtils.currentDate(); 9

10 public void getLog(Integer size){

11 String systTime = DateUtils.currentDate();12 //如果⽇期不是当天的

13 if(today!=null && !systTime.equals(today)){14 synchronized (today) {

15 if(today!=null && !systTime.equals(today)){16 today=systTime;17 count.set(0);18 dataSize.set(0);19 }20 }21 }

22 count.incrementAndGet();23 dataSize.addAndGet(size);24 if(logger.isInfoEnabled()) {

25 logger.info(String.format(\"That day receive data the %sth times,total %s data !\26 }27 }

还有很关键的⼀个问题不要忽略,就是该类是单例的,这样确保所有线程共享同⼀个count,dataSize只有⼀个对象!或者将count,dataSize设置成static!!

因篇幅问题不能全部显示,请点此查看更多更全内容