这是程序
public class Thread2 implements Runnable {
private static int runTill = 10000;
private static int count = 0;
@Override
public void run() {
for(int i=0;i<runTill;i++) {
count++;
}
}
public static void main(String s[]) {
int iteration = 10;
for(int i = 0; i < iteration ;i++) {
Thread t = new Thread(new Thread2());
t.start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Expected : "+(iteration * runTill));
System.out.println("Actual : "+count);
}
}
最后我希望计数等于(预期:100000)。我怎样才能做到这一点?
答案 0 :(得分:2)
对 count++
的调用不是原子的:它首先必须加载 count
,将其递增,然后将新值存储在变量中。如果没有同步,线程将在执行此操作期间交错。
获得所需内容的一种简单方法是使用 AtomicInteger
:
private static AtomicInteger count = new AtomicInteger();
@Override
public void run() {
for(int i=0;i<runTill;i++) {
count.incrementAndGet();
}
}
答案 1 :(得分:0)
使用“比较并设置”而不是“递增并获取”
private static AtomicInteger count = new AtomicInteger();
@Override
public void run() {
for(int i=0;i<runTill;i++) {
//note: another thread might reach this point at the same time when i is 9,999
// (especially if you have other codes running prior to the increment within the for loop)
// then count will be added 2x if you use incrementAndGet
boolean isSuccessful = count.compareAndSet(i, i+1);
if(!isSuccessful)
System.out.println("number is not increased (another thread already updated i)");
}
}
答案 2 :(得分:0)
正如评论所暗示的,除了需要同步访问(到 count
,这里变成了 AtomicInteger
),线程应该等待使用 Thread.join()
完成,而不是“猜测”他们的运行时间:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Thread2 implements Runnable {
private static int runTill = 10000;
private static AtomicInteger count = new AtomicInteger();
@Override
public void run() {
for (int i = 0; i < runTill; i++) {
count.incrementAndGet();
}
}
public static void main(String s[]) {
int iteration = 10;
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < iteration; i++) {
Thread t = new Thread(new Thread2());
threads.add(t);
t.start();
}
try {
for (Thread t : threads)
t.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("Expected : " + (iteration * runTill));
System.out.println("Actual : " + count);
}
}