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

谁能解释一下结果?

谁能解释一下结果?

红颜莎娜 2024-01-05 09:55:50
public class Bank {    private  int sum=0;    public void add(int n) {        try {            Thread.sleep(10);        } catch (InterruptedException e) {            e.printStackTrace();        }        sum+= n;        System.out.println(sum);    }}public class Consumer implements Runnable {    Bank bank = new Bank();    @Override    public void run() {        for (int i = 0; i < 10; i++) {            bank.add(100);        }     }}public class Tes2 {    public static void main(String[] args) {        Consumer consumer = new Consumer();        Thread thread1 = new Thread(consumer);        Thread thread2 = new Thread(consumer);        thread1.start();        thread2.start();    }}这是一个多线程程序,模拟多个储户到银行存钱,用来演示多线程的安全问题。由于代码不同步,它的第一、第二个结果可能是200/200,200/300,等等。但是我不明白为什么你得到100/100,谁能解释一下?
查看完整描述

2 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

这是一个竞争条件。

两个线程都可以访问 sum。

总和+=n;不是原子的

线程 1 读取 sum 0

线程 2 换入,因为代码未同步,读取 sum 为 0

线程 1 将 100 加到 0 并将其写入总和

线程 2 将 0 加 100 并将其写入总和并覆盖线程 1 的值


查看完整回答
反对 回复 2024-01-05
?
神不在的星期二

TA贡献1963条经验 获得超6个赞

如果您仅根据代码中的行来考虑该程序的并发性,那么 100/100 的输出结果就没有意义。但您还必须考虑执行这些行时实际发生的指令是什么。每行代码可以包含很多很多汇编指令。在这种情况下,要添加nsum,真正发生的是从内存中读取 的值sum,可能加载到寄存器中,递增,然后重新写入内存中。

100/100 输出可能发生在以下场景中。假设线程 1 和线程 2 都调用bank.add(100),并且银行异步处理请求。也就是说,银行有一个线程处理每个请求。

然后,该组的线程 1 加载 的值sum,该值为零。线程 2 还加载了紧随其后的值sum,该值仍然为零。然后,线程 1 获取它加载的值,添加n=100,并将其写入内存。线程2做同样的事;它采用之前加载的 sum 值 0,加上 100,然后将其写回内存。然后,他们各自打印出 100 的值。


查看完整回答
反对 回复 2024-01-05
  • 2 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信