为了账号安全,请及时绑定邮箱和手机立即绑定

适合新手的并发编程

适合新手的并发编程

阿晨1998 2022-05-21 14:08:30
我正在尝试理解并发编程,但我不确定一件事。我有一个有两个线程的程序,它们递增相同的 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());    }}
查看完整描述

2 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

两个线程都可以将 的值复制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);

使用 sharedn时,n 不会增加 2,而只会增加 1。


synchronize (n) {

    temp = n.getN();

    n.setN(temp + 1);

}

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


查看完整回答
反对 回复 2022-05-21
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

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

  1. 不能保证一个线程对共享变量所做的更改对另一个线程可见

  2. n在读取to的当前值和写入递增值之间存在竞争条件temp- 另一个线程可能已经修改了两者之间的值,然后这将被覆盖

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


查看完整回答
反对 回复 2022-05-21
  • 2 回答
  • 0 关注
  • 106 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号