java - 适合新手的并发编程

标签 java concurrency

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

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());
    }
}

最佳答案

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

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

static volatile IntCell n

另一个问题是原子性失败,关键区域:

// Thread 1    // Thread 2
temp = n.getN();
               temp = n.getN();
               n.setN(temp + 1);
n.setN(temp + 1);

如果使用共享的n,则 n 不会增加 2,而只会增加 1。

synchronize (n) {
    temp = n.getN();
    n.setN(temp + 1);
}

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

关于java - 适合新手的并发编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54324716/

相关文章:

scala - Akka Actor 消息延迟

java - Java对象的并发

java - 如何在某些源上创建并发迭代器?

java - 我如何制作像电视那样的静态屏幕效果?

java - 用Java实现简单链表

javamail 问题 : how to attach file without creating file

Java 8 并行流实际上并没有并行工作

node.js - 慢速磁盘 I/O 是否会降低 Node.js 应用程序其余部分的性能?

java - 将int文字传递给在java中采用整数的方法

java - 基本数学运算