java - 多线程程序中出现意外结果

标签 java arrays multithreading

这个简单的程序有一个共享数组和 2 个线程: 第一个线程 - 显示数组中值的总和。 第二个线程 - 从数组的一个单元格中减去 200,并向另一个单元格添加 200。

我希望看到结果:1500(数组的总和),1300(如果显示发生在减法和加法之间)。

但是由于某种原因,有时会出现1100和1700,我无法解释......

public class MainClass {

    public static void main(String[] args) {
        Bank bank = new Bank();
        bank.CurrentSum.start();
        bank.TransferMoney.start();
    }
}

class Bank {
    private int[] Accounts = { 100, 200, 300, 400, 500 };
    private Random rnd = new Random();

    Thread CurrentSum = new Thread("Show sum") {
        public void run() {
            for (int i = 0; i < 500; i++) {
                System.out.println(Accounts[0] + Accounts[1] + Accounts[2]
                        + Accounts[3] + Accounts[4]);
            }
        }
    };

    Thread TransferMoney = new Thread("Tranfer"){
        public void run(){
            for(int i=0; i<50000; i++)
            {
                Accounts[rnd.nextInt(5)]-=200;
                Accounts[rnd.nextInt(5)]+=200;
            }
        }
    };
}

最佳答案

您没有以原子或线程安全的方式更新值。这意味着有时您会看到 -200 比 +200 多两个,有时您会看到 +200 比 -200 多两个。当您迭代这些值时,可能会看到 +200 值,但 -200 值是较早的值,您会错过它,但您会再次看到另一个 +200 更新,缺少 -200 更改。

在极少数情况下,应该可以看到最多 5 x +200 或 5 x -200。

关于java - 多线程程序中出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27769395/

相关文章:

Java:在线程池中共享多个递归任务的工作人员

java - 在第二个 Activity 中删除记录后 ListView 未更新

javascript - 获取对象数组中的特定元素

javascript - 如何从数组中检查

c++ - GCC 4.8 中 C++11 线程局部变量的性能损失是什么?

java - 无法访问未找到 org.apache.commons.pool2.impl.GenericObjectPoolConfig 的 org.apache.commons.pool2.impl.GenericObjectPoolConfig 类文件

Ant脚本生成的Java Jar不支持用户输入

c++ - 删除运算符和数组?

multithreading - 'else' 与 i/o 结合的可疑使用,在 ';' 附近看到了 'if'

javascript - 我可以使用 Nashorn 在新引擎作用域中调用函数吗?