需求背景
在一个发短信的业务平台中,需要统计发送短信的总数,每一个任务对应一个号码文件,每一个任务也都会new 一个新的进程来执行。
用户发来两个任务,一个号码总数为100,一个号码总数为5000。
发送完成后查看数据,发现第一个任务数据无误(总数为100),第二个数据有误(总数为5100)。
问题分析
由于数量很对应,很容易发现问题所在,应该是第二个任务累加了第一个任务的数据。
最初的想法是多线程操作一个属性造成的原因,但是每一个任务的线程都是独立运行的,且每一次都会new一个新的执行对象,也会对总数进行初始赋值,所以排除了这种可能性。
然后意识到可能是这个变量是一个被共享使用变量,两个线程操作的是一个同一个变量。这种情况可能是单例对象产生的,不过很快又排除了,在spring配置中并没有配置这个类是单例的。
在代码中又进行了查看,发现在类的成员变量中号码总数有 static 关键字修饰,恍然大悟。
private static long FolderNumCount = 0;
Static关键字解析
Static变量
++静态成员变量,又称类变量,只会在类初始化的时候创建一次。
先上代码,最后讲原理。++
StaticVariable类
public class StaticVariable {
// 静态变量
private static int testStatic = 0;
// 普通变量
private int general = 0;
// +1操作