JAVA 对 int 高性能累加
现在我要实现一个功能,做一个在线用户数统计功能,这是一个多线程的环境,同时访问的用户数非常大,我把在线用户数放在一个 int 里。它的工作流程大致如下:
用户请求过来,我 int 加 1,等用户请求处理完,我 int 减 1。
private int online = 0;
public synchronized void plus() {
online++;
}
public synchronized void minus() {
online--;
}
现在有一个问题,如果我用 synchronized 来同步,感觉性能上会有影响,如果不用synchronized ,用来统计的 int 数据又不准确。所以想问下各位,有没有更好的解决方案。
------最佳解决方案--------------------哦,所以你这个其实并不是Session意义上的在线。而是:当前并发数。
这种问题一般用分割计数器的方式来处理,也即:
初始化:
private static final int CONCURREN_RATE = 100;
Counter[] cs = new Counter[CONCURREN_RATE];
// 初始化略。。。
使用时:
Counter c = cs[hash(用户对象) % CONCURREN_RATE];
c.plus();
统计一般是定期统计,把所有Counter做个求和就行了,对于统计来说,一般其实也不需要精准;也就是可以脏读,不要去synchronized了。
不过你这个还不是最困难的,呵呵,困难的是集群环境下,还要做合并。
------其他解决方案--------------------可以如下改动,对性能会有所提高
private int online = 0;
//使用同步块而不使用同步方法,使得占用锁的时间较少来提升性能。
public void plus() {
synchronized(this) {
online++;
}
}
public void minus() {
synchronized(this) {
online--;
}
}
private AtomicInteger online = new AtomicInteger(0);
//因为AtomicInteger是原子操作,所以不用同步。这种方式要比上一种更加能提升性能。
public void plus() {
online.getAndIncrement();
}
public void minus() {
online.getAndDecrement();
}
------其他解决方案--------------------在线用户数,没有那么高的并发性;又不是统计访问量啥的;用户不会频繁的登录登出的。
如果是淘宝之类的话,可能还稍微需要考虑下这种问题。
------其他解决方案--------------------
我这个在线访问不是用于网站的 session ,我做的是一个接口系统,一个用户一次访问可能只有几百毫秒就结束了。至于访问量,后面也会做,所以对这个 int 做实时操作非常频繁。
------其他解决方案--------------------
Counter 是什么类?
------其他解决方案--------------------
是不是自己封装的,里面就是封装我的那个方法。
------其他解决方案--------------------
Counter就是你自己封装的计数器了,直接用AtomicInteger也行,看场合。
AtomicInteger的缺点是超高并发下性能表现会搓,大部分情况下会比synchronized更好。