问题描述:我本来想使用线程池(ExecutorService)+ Callable实现多线程处理数据,测试过程发现,只循环2到3次时,最终输出的数据只有最后一次遍历的数据(很奇怪!!!)。遇到问题解决问题。
1、首先把我的测试代码贴出来
1.1、测试代码
// 测试的main函数
public static void main(String[] args) throws Exception {
//调用工厂类的静态方法,创建线程池对象
//返回线程池对象,是返回的接口
ExecutorService pool = Executors.newFixedThreadPool(2); // 创建固定个数线程池对象
for (int i = 0; i < 2; i++) {
String xm = "姓名" + i;
Callable callable = new MyCallable(xm, i);
Future<String> f = pool.submit(callable);提交线程任务
}
pool.shutdown();//停掉线程
}
Callable类:主要业务逻辑在这处理
public class MyCallable implements Callable<Object> {
public static String xm ="";
public static int count = 0;
public MyCallable() {
}
public MyCallable(String xmi,int counti) throws Exception {
this.xm = xmi;
this.count = counti;
};
@Override
public Object call() throws Exception {
System.out.println(count);
System.out.println(xm);
return null;
}
}
1.2、第一次的输出结果
只输出了第二次的,没有第一次的数据。
2、排查过程如下
一开始我以为是不是两次循环间时间太短,让最后一次的把第一次的覆盖了,然后我开始逐渐增加循环次数。
2.1、循环10次
还是不正常
2.2、循环100次
数据有一丢丢的好转了起码姓名不全是最后一个了,看来只靠增加循环次数是不行了,直接Sleep。
2.3、线程暂停1秒
是正常的
难道真是被最后覆盖了吗?仔细想一下,如果被覆盖那么只能是在同一个内存空间,朝着这个方向排查一下?排查什么呢?方法?变量?那肯定是变量了。
唯一不太寻常的地方就是这里定义的是静态变量,看一下静态变量怎回事?
从上面的定义分析真是静态变量的原因吗?试试吧
修改代码:
把static关键字去掉
把main函数的sleep注释掉
测试:
正常了!!!!!!!!!!!!!!!!!!!!!!!
问题解决!!!!!!!!!!!!!!!!!!!!!!
吟诗一首啊:
编写程序不容易
排查问题难上难
过程确实很坎坷
结果真的很美丽