首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >新手并发编程

新手并发编程
EN

Stack Overflow用户
提问于 2019-01-23 10:08:20
回答 2查看 58关注 0票数 0

我试图理解并发编程,但我不确定有一件事。我有一个程序,它有两个线程,它们增量相同的int (IntCell n)。在200,000循环之后,int应该是400,000,但它超过了20万。现在我想知道其中一个线程是否被征用了,当第二个线程正在递增它时,或者它们只是一个一个地读取相同的值,然后增量它并将它设置为int 2次(设置相同int的两个操作)。下面是代码:

代码语言:javascript
复制
class IntCell {
    private int n = 0;
    public int getN() {return n;}
    public void setN(int n) {this.n = n;}
}

class Count extends Thread {
    private static IntCell n = new IntCell();

    @Override
    public void run() {
        int temp;
        for (int i = 0; i < 200000; i++) {
            temp = n.getN();
            n.setN(temp + 1);
        }
    }

    public static void main(String[] args) {
        Count p = new Count();
        Count q = new Count();
        p.start();
        q.start();
        try { p.join(); q.join(); }
        catch (InterruptedException e) { }
        System.out.println("The value of n is " + n.getN());
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-23 10:25:11

两个线程都可以将static IntCell n的值复制到它们的线程本地存储中。

使用volatile关键字向线程发出信号,以同步线程本地值和共享值。

代码语言:javascript
复制
static volatile IntCell n

另一个问题是原子性不佳,即:

代码语言:javascript
复制
// Thread 1    // Thread 2
temp = n.getN();
               temp = n.getN();
               n.setN(temp + 1);
n.setN(temp + 1);

对于共享的n,这将增加n而不是2,而只是1。

代码语言:javascript
复制
synchronize (n) {
    temp = n.getN();
    n.setN(temp + 1);
}

这确保了与n关联的信号量上的关键区域阻塞。

票数 1
EN

Stack Overflow用户

发布于 2019-01-23 10:27:11

您没有使用任何类型的同步,这导致了两个主要问题:

  1. 不能保证一个线程对共享变量所做的更改对另一个线程是可见的。
  2. 在将n的当前值读取到temp和写入递增的值之间存在一个争用条件,另一个线程可以在两者之间修改该值,然后重写该值。

可能的解决方案包括使用synchronized-blocks、包java.util.concurrent.locks中的锁或支持原子更新的类型(如AtomicInteger )。

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

https://stackoverflow.com/questions/54324716

复制
相关文章

相似问题

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