适合新手的并发编程

我正在尝试理解并发编程,但我不确定一件事。我有一个有两个线程的程序,它们递增相同的 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());

    }

}


阿晨1998
浏览 107回答 2
2回答

守候你守候我

两个线程都可以将 的值复制static IntCell n到它们的线程本地存储中。使用volatile关键字向线程发出信号以同步线程本地值和共享值。static volatile IntCell n另一个问题是原子性失败,关键区域:// Thread 1&nbsp; &nbsp; // Thread 2temp = n.getN();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;temp = n.getN();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;n.setN(temp + 1);n.setN(temp + 1);使用 sharedn时,n 不会增加 2,而只会增加 1。synchronize (n) {&nbsp; &nbsp; temp = n.getN();&nbsp; &nbsp; n.setN(temp + 1);}这确保了一个关键区域阻塞在与 相关联的信号量上n。

缥缈止盈

您没有使用任何类型的同步,这会导致两个主要问题:不能保证一个线程对共享变量所做的更改对另一个线程可见n在读取to的当前值和写入递增值之间存在竞争条件temp- 另一个线程可能已经修改了两者之间的值,然后这将被覆盖可能的解决方案包括使用synchronized-blocks、数据包中的锁java.util.concurrent.locks或支持原子更新的类型,例如AtomicInteger
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java