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

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

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

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

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

复制代码

 1 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
 2 
 3 /**
 4      * 获得当前日期
 5      * <p>
 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 !",count.get(),dataSize.get()));
26         }
27     }

复制代码

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值