非线程安全行为-竞赛条件永远不会发生

时间:2018-10-24 17:06:41

标签: java multithreading

尝试这段代码,我发现无论我运行程序多少次或完成迭代,都不会发生竞争条件。我知道这不是线程安全的,而且我不明白发生此行为的原因。欢迎任何文档/想法。

Main.java

public class Main {
    static final int N = 1000;
    static int ITERATIONS = 1000000;

    public static void main(String[] args) {
        Thread threads[] = new Thread[10];
        boolean found = true;
        for (int j = 0; j < ITERATIONS; j++) {
            MyThread.val = 0;
            for (int i = 0; i < 10; i++)
                threads[i] = new Thread(new MyThread());
            for (int i = 0; i < 10; i++)
                threads[i].run();
            for (int i = 0; i < 10; i++) {
                try {
                    threads[i].join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (MyThread.val != N * 10) {
                System.out.println("different !");
                found = false;
            }
        }
        if (found)
            System.out.println("The value is always correct.");
    }
}

MyThread

public class MyThread implements Runnable {
    static int val = 0;

    @Override
    public void run() {
        for (int i = 0; i < Main.N; i++)
            val = val + 1;
    }
}

我尝试运行该程序数十次,但始终会打印 “值始终正确”。

(这不是家庭作业或其他内容)

3 个答案:

答案 0 :(得分:1)

您实际上并没有启动任何线程。调用Thread.run()仅在当前线程中运行线程的活动。如果要在方法中打印开始和结束时间戳记,则可能会观察到。

致电Thread.start()而不是Thread.run()来观察您要寻找的内容。

答案 1 :(得分:1)

您的代码没有竞争条件,因为它在单个线程中运行。

方法run仅调用其Runnable对象的run方法,而无需创建新线程。 (如果没有Runnable对象,则不执行任何操作)

方法start实际上启动了一个同时运行的新线程。

文档:

答案 2 :(得分:-1)

竞争条件将显示在中间值中,但不应影响最终值。 val总是会增加相同的次数,它只会在增加线程间来回跳动。如果您在每个线程中存储了一个本地val(并带有一个新类)并对其进行了递增,则您会注意到本地值的更新速率与全局值不同,并且该速率可能会有很大的变化程序运行时。