尝试这段代码,我发现无论我运行程序多少次或完成迭代,都不会发生竞争条件。我知道这不是线程安全的,而且我不明白发生此行为的原因。欢迎任何文档/想法。
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;
}
}
我尝试运行该程序数十次,但始终会打印 “值始终正确”。
(这不是家庭作业或其他内容)
答案 0 :(得分:1)
您实际上并没有启动任何线程。调用Thread.run()
仅在当前线程中运行线程的活动。如果要在方法中打印开始和结束时间戳记,则可能会观察到。
致电Thread.start()
而不是Thread.run()
来观察您要寻找的内容。
答案 1 :(得分:1)
您的代码没有竞争条件,因为它在单个线程中运行。
方法run
仅调用其Runnable对象的run
方法,而无需创建新线程。 (如果没有Runnable对象,则不执行任何操作)
方法start
实际上启动了一个同时运行的新线程。
文档:
答案 2 :(得分:-1)
竞争条件将显示在中间值中,但不应影响最终值。 val
总是会增加相同的次数,它只会在增加线程间来回跳动。如果您在每个线程中存储了一个本地val
(并带有一个新类)并对其进行了递增,则您会注意到本地值的更新速率与全局值不同,并且该速率可能会有很大的变化程序运行时。