猿问

谁能解释一下结果?

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,谁能解释一下?


红颜莎娜
浏览 105回答 2
2回答

撒科打诨

这是一个竞争条件。两个线程都可以访问 sum。总和+=n;不是原子的线程 1 读取 sum 0线程 2 换入,因为代码未同步,读取 sum 为 0线程 1 将 100 加到 0 并将其写入总和线程 2 将 0 加 100 并将其写入总和并覆盖线程 1 的值

神不在的星期二

如果您仅根据代码中的行来考虑该程序的并发性,那么 100/100 的输出结果就没有意义。但您还必须考虑执行这些行时实际发生的指令是什么。每行代码可以包含很多很多汇编指令。在这种情况下,要添加n到sum,真正发生的是从内存中读取 的值sum,可能加载到寄存器中,递增,然后重新写入内存中。100/100 输出可能发生在以下场景中。假设线程 1 和线程 2 都调用bank.add(100),并且银行异步处理请求。也就是说,银行有一个线程处理每个请求。然后,该组的线程 1 加载 的值sum,该值为零。线程 2 还加载了紧随其后的值sum,该值仍然为零。然后,线程 1 获取它加载的值,添加n=100,并将其写入内存。线程2做同样的事;它采用之前加载的 sum 值 0,加上 100,然后将其写回内存。然后,他们各自打印出 100 的值。
随时随地看视频慕课网APP

相关分类

Java
我要回答