此代码从不同的蒸汽数据中读取数字,并输出总和。这段代码有问题吗?我该如何解决?
public class Thr extends Thread{
static int numThr=100, sum=0;
private int num;
private Thr(int num){this.num =num;}
public void run() {
int k = IntegerReader.get(num);
int count=0;
while(k>0) {
if(count%numThr==num) sum+=k;
count++;
k=IntegerReader.get(num);
}
}
public static void main(String[] a) throws Exception {
thr[] st =new thr[numThr];
for(int i=0; i<numThr; i++) st[i] = new Thr(i);
for(int i=0; i<numThr; i++) st[i].start();
System.out.println("sum = "+sum);
}
}
答案 0 :(得分:1)
马上就有很多不妥之处。
Sum在多个线程之间共享,并在多个线程中递增,这意味着您可以获得不一致的值,因为递增值不是原子操作。
最简单的解决方法是将sum的声明更改为:
private static AtomicInteger sum = new AtomicInteger(0);
并以这种方式添加:
sum.getAndAdd(k)
“numThr”在多个线程之间共享,并由多个线程读取。由于numThr不是final,synchronized或volatile,因此无法保证其他线程将看到其值已初始化。 numThr应声明为private static final int numThr=100
您的System.out.println("sum = "+sum);
将在线程执行完毕之前打印出来。在打印总和之前,您需要在线程上“加入”(即等待它们完成)。在sysout之前添加:for(int i=0; i<numThr; i++) st[i].join();
。
我认为你应该阅读Java内存模型和Java中的并发性。 这是一个基础教程,但你真的需要一本关于这个主题的书: http://docs.oracle.com/javase/tutorial/essential/concurrency/
答案 1 :(得分:0)
是的,此代码有几个问题。解决问题的一种方法是花时间阅读并理解Java tutorial。另一种方法是让其他人为你修理它,但要注意这种东西在这里不会很好。