首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AtomicReference的单个元素上的数据竞争

AtomicReference的单个元素上的数据竞争
EN

Stack Overflow用户
提问于 2016-10-30 20:03:08
回答 2查看 135关注 0票数 1

我有一个关于通过原子引用访问单个元素的问题。如果我有一个IntegerArray和它的原子引用;通过AtomicReference变量读取和写入数组的各个元素会导致数据竞争吗?

在下面的代码中: num是一个整数数组,aRnumbers是该数组的原子引用。在线程1和线程2中,我访问aRnumbers.get()1并将其增加1。

我能够通过原子引用访问各个元素,而不需要数据竞争,每次都要以22作为主线程中aRnumbers.get()1的输出,在两个线程完成之后。

但是,由于原子引用是在数组上定义的,而不是在单个元素上定义的;在这种情况下,不应该有一个数据竞争导致21/22作为输出吗?

在这种情况下,拥有数据竞赛不是AtomicIntegerArray数据结构为每个元素提供一个单独的AtomicReference的动机吗?

请在下面的java代码中找到我正在尝试run.Could的任何人,请让我知道我哪里出错了。

代码语言:javascript
复制
import java.util.concurrent.atomic.AtomicReference;

public class AtomicReferenceExample {


    private static int[] num= new int[2];
    private static AtomicReference<int[]> aRnumbers;

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new MyRun1());
        Thread t2 = new Thread(new MyRun2());

        num[0]=10;
        num[1]=20;

        aRnumbers = new AtomicReference<int[]>(num);

        System.out.println("In Main before:"+aRnumbers.get()[0]+aRnumbers.get()[1]);

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        System.out.println("In Main after:"+aRnumbers.get()[0]+aRnumbers.get()[1]);
    }

    static class MyRun1 implements Runnable {
        public void run() {
            System.out.println("In T1 before:"+aRnumbers.get()[1]);
            aRnumbers.get()[1]=aRnumbers.get()[1]+1;

        }
    }

    static class MyRun2 implements Runnable {
        public void run() {
            System.out.println("In T2 before:"+aRnumbers.get()[1]);
            aRnumbers.get()[1]=aRnumbers.get()[1]+1;

        }

    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-10-30 20:09:54

在这种情况下,难道不应该有一个数据竞赛导致输出为21/22吗?

的确有。您的线程寿命太短,很可能它们不在同一时间运行。

在这种情况下,拥有数据竞赛不是AtomicIntegerArray数据结构为每个元素提供一个单独的AtomicReference的动机吗?

是的,是这样的。

有谁能告诉我我哪里出错了吗?

启动线程需要1-10毫秒。

即使没有代码是JITed,增加这样的值可能会占用<< 50微秒。如果对其进行优化,每增加大约50到200纳米秒。

由于启动线程所需时间比运行时间长约20-200倍,因此不会同时运行,因此没有比赛条件。

尝试将值递增几百万次,这样您就有了一个争用条件,因为两个线程同时运行。

票数 0
EN

Stack Overflow用户

发布于 2016-10-30 20:15:49

递增元素由三个步骤组成:

  1. 读取价值。
  2. 递增值。
  3. 把价值写回去。

种族状况可能会发生。举个例子:线程1读取值(比方说20)。任务切换。线程2读取值(再读20次),增加值并将其写回(21)。任务切换。第一个线程增加该值并将其写回(21)。因此,在进行2次递增操作时,最终值仍然只增加1次。

在这种情况下,数据结构没有帮助。线程安全集合有助于在并发线程添加、访问和删除元素时保持结构的一致性。但是在这里,您需要在增量操作的三个步骤中锁定对元素的访问。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40333054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档