AtomicInteger增量不符合预期

卡皮尔·拉朱(Kapil Raju)

我正在阅读有关AtomicInteger的内容,以及它的操作是原子的以及这些属性如何使其对多线程有用。

我编写了以下程序来进行测试。

我期望该集合的最终大小应该为1000,因为每个线程循环执行500次,并假设每次线程调用getNext()时,它应该获得一个唯一的数字。

但是输出总是小于1000。我在这里缺少什么?

public class Sequencer {

private final AtomicInteger i = new AtomicInteger(0);

public int getNext(){
    return i.incrementAndGet();
}

public static void main(String[] args) {

    final Sequencer seq = new Sequencer();

    final Set<Integer> set = new HashSet<Integer>();

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i=0; i<500; i++)
                set.add(seq.getNext());

        }
    },"T1");
    t1.start();


    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i=0; i<500; i++)
                set.add(seq.getNext());

        }
    },"T2");

    t2.start();

    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(set.size());

}

}

两个

您缺少HashSet不是线程安全的。另外,集合的属性将删除所有重复的数字,因此,如果AtomicInteger不是线程安全的,则测试将失败。

尝试改用ConcurrentLinkedQueue

编辑:因为已经被询问过两次:使用同步集有效,但是它破坏了使用诸如Atomic-classes之类的无锁算法的想法。如果在上面的代码中用同步集替换了该集,则每次add调用时线程将不得不阻塞

这将有效地将您的应用程序减少到单线程,因为完成的唯一工作是同步进行的。实际上,它甚至会比单线程慢,因为synchronized它也要付出代价。因此,如果您想实际利用线程,请尽量避免synchronized

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章