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