Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 谁能解释结果? 公共类银行{ 私有整数和=0; 公共无效添加(整数n){ 试一试{ 睡眠(10); }捕捉(中断异常e){ e、 printStackTrace(); } 总和+=n; 系统输出打印项数(总和); } } 公共类使用者实现可运行{ 银行=新银行(); @凌驾 公开募捐{ 对于(int i=0;i_Java_Multithreading - Fatal编程技术网

Java 谁能解释结果? 公共类银行{ 私有整数和=0; 公共无效添加(整数n){ 试一试{ 睡眠(10); }捕捉(中断异常e){ e、 printStackTrace(); } 总和+=n; 系统输出打印项数(总和); } } 公共类使用者实现可运行{ 银行=新银行(); @凌驾 公开募捐{ 对于(int i=0;i

Java 谁能解释结果? 公共类银行{ 私有整数和=0; 公共无效添加(整数n){ 试一试{ 睡眠(10); }捕捉(中断异常e){ e、 printStackTrace(); } 总和+=n; 系统输出打印项数(总和); } } 公共类使用者实现可运行{ 银行=新银行(); @凌驾 公开募捐{ 对于(int i=0;i,java,multithreading,Java,Multithreading,这是一个多线程程序,模拟多个储户到银行存款,用于演示多线程安全问题。由于代码不同步,其第一次和第二次结果可能是200/200200/300,依此类推。但我不明白为什么会得到100/100,谁能解释呢?如果仅仅根据代码中的行来考虑这个程序的并发性,那么100/100输出结果就没有意义了。但您还必须考虑在执行这些行时实际发生的指令。每一行代码都可以由很多很多汇编指令组成。在这种情况下,要将n添加到sum,实际发生的是从内存中读取sum的值,可能会加载到寄存器中,然后递增,然后重新写入内存 100/1

这是一个多线程程序,模拟多个储户到银行存款,用于演示多线程安全问题。由于代码不同步,其第一次和第二次结果可能是200/200200/300,依此类推。但我不明白为什么会得到100/100,谁能解释呢?

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

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


然后,该组的线程1加载
sum
的值,该值为零。线程2还加载紧跟其后的
sum
值,该值仍然为零。然后,线程1获取加载的值,添加
n=100
,并将其写入内存。线程2也会这样做;它取以前加载的sum值0,加上100,然后将其写回内存。然后,它们各自打印出100的值。

这是一个竞争条件

两个线程都可以访问sum

总和+=n;它不是原子的

线程1读取和0

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

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


线程2将100与0相加,并将其写入覆盖线程1s值的总和中,解决方案是要么使用正确的同步,要么更简单地使用AtomicInteger。谢谢,Cwrwhaf!我得到点和+=n;不是原子的,我以为是原子的!再次感谢你!
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();
    }
}