作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个类,它在各自的线程上创建许多新对象,我想保持跨线程的运行计数。我想要一个 AtomicInteger
但它没有达到我的预期,而只是得到了一个较小的版本。我假设这是一个竞争条件错误 - 但我不完全确定。
A 创建了这个测试示例,它重新创建了我想做的事情。
public class Test {
public static void main(String args[]) {
AtomicInteger total = new AtomicInteger(0);
for (int i = 0; i < 10; i++) {
DoThing doThing = new DoThing();
Thread thread = new Thread(doThing);
thread.start();
total.addAndGet(doThing.getTally());
}
System.out.println(total.get());
}
}
class DoThing implements Runnable {
int tally = 0;
@Override
public void run() {
for(int i = 0; i< 100; i++) {
tally++;
}
System.out.println("Tally is " + tally);
}
public int getTally() {
return tally;
}
}
但是,这会输出:
Tally is 100
Tally is 100
Tally is 100
Tally is 100
Tally is 100
Tally is 100
Tally is 100
Tally is 100
0
Tally is 100
Tally is 100
当我希望最终输出为 1000 时。如何跨线程递增?
提前致谢。
最佳答案
试试这个:
public static void main(String args[]) {
AtomicInteger tally = new AtomicInteger(0);
List<Thread> threadList = new ArrayList<Thread>();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new DoThing(tally));
t.start();
threadList.add(t);
}
for (Thread t : threadList) {
try { t.join(); } catch (Exception e){}
}
System.out.println("Total tally: " + tally.get());
}
public static class DoThing implements Runnable {
private static final Random rand = new Random();
private final AtomicInteger tally;
public DoThing(AtomicInteger tally) {
this.tally = tally;
}
@Override public void run() {
for (int i = 0; i < 100; i++) {
int currTally = tally.incrementAndGet();
System.out.println("Thread " + Thread.currentThread().getName() + ": " + currTally);
// Random sleep to show that your threads are properly concurrently incrementing
try { Thread.sleep(rand.nextInt(10)); } catch (Exception e) {}
}
}
}
问题的根源在于您误解了如何使用 AtomicInteger
,您将其视为普通的 int
并且根本没有同时访问它.
此外,getTally()
也是一个竞争条件,直到您通过调用 Thread.join()
确保线程已完成为止。
因此,您可以通过让线程中的所有 Runnable
更新相同的 AtomicInteger
实例来保持最新的计数,并且您可以确保您拥有通过在获取计数之前通过 join()
等待所有线程完成计数,可以得到正确的总数。
关于java - 从其他线程更新 AtomicInteger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48936177/
我是一名优秀的程序员,十分优秀!