AtomicInteger不会同时增加 [英] AtomicInteger doesn't increment concurrently

查看:129
本文介绍了AtomicInteger不会同时增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试类 AtomicInteger 的使用,但在互斥控制下似乎未应用增量。

I am testing the use of the class AtomicInteger but increments doesn't seem to be applied under mutual exclusion control.

这是我的测试:

static class AtomicIntegerRunnable implements Runnable
{
    private static AtomicInteger x;

    AtomicIntegerRunnable() {}

    AtomicIntegerRunnable(AtomicInteger x) 
    {
        this.x = x;
    }

    @Override
    public void run()
    {
        System.out.println(x.get());
        x.getAndIncrement();
    }
}

public static void main(String[] args) {
    ExecutorService e = Executors.newFixedThreadPool(n_whatever);
    AtomicInteger x = new AtomicInteger();
    int n = 10;
    for (int i=0; i<n; i++) {
        e.submit(new AtomicIntegerRunnable(x));
            }
    e.shutdown();
    while (!e.isTerminated());
}

在印刷品中,我得到的是

In the print I am getting something like


0 0 1 1 1 5 5 4 3 2 6

0 0 1 1 1 5 4 3 2 6

而不是


0 1 2 3 4 5 6 7 8 9

0 1 2 3 4 5 6 7 8 9

。怎么了?

编辑 @Louis Wasserman

EDIT for @Louis Wasserman

static class AtomicIntegerRunnable implements Runnable
{
    private AtomicInteger x;

    AtomicIntegerRunnable() {}

    AtomicIntegerRunnable(AtomicInteger x) 
    {
        this.x = x;
    }

    @Override
    public void run()
    {
        x.getAndIncrement();
    }
}

public static void main(String[] args) 
{
    ExecutorService e = Executors.newFixedThreadPool(n_whatever);
    AtomicIntegerRunnable x = new AtomicIntegerRunnable(new AtomicInteger());
    int n = 10;
    for (int i=0; i<n; i++) 
        e.submit(x);
    e.shutdown();
    while (!e.isTerminated());
}


推荐答案

您正在获取并递增它以两个单独的动作。您正在打印第一个,这使得您自己的代码不是原子的。

You are getting it and incrementing it in two separate actions. You are printing out the first, which makes your own code non-atomic.

每个AtomicInteger操作都是原子的,但是您不能依次使用两个并考虑原子的组合-从定义上讲,两个操作不是原子的。

Each AtomicInteger operation is atomic on its own, but you cannot use two in sequence and consider the combination atomic -- by defintion, two operations are not atomic.

要解决此问题:

@Override
public void run()
{
    System.out.println(x.getAndIncrement());
}

但是,正如评论中指出的那样,您有动作,进行打印。增量操作也不是原子的。因此,您需要同步两者以使列表按顺序打印出来。

However, as pointed out in the comments, you have a third action, the printing. This is also not atomic with the increment action. So, you would need to synchronize the two in order to make your list print out in order.

您可以调用该方法 printAndIncrement

通常,AtomicInteger通常用于确保多线程代码永远不会意外地对同一整数进行操作,而不是确保外部系统(例如输出缓冲区) )按顺序查看这些增量(因为您仍需要其他东西来与该外部系统同步通信)。

Usually AtomicInteger is used more to ensure that multithreaded code never accidentally operates on the same integer, not to ensure that an external system (like an output buffer) sees those increments in order (because you still need something else to synchronize communication with that external system).

这篇关于AtomicInteger不会同时增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆