gpt4 book ai didi

java - 为什么主线程不能比较两个由其他线程更新的变量?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:36:54 25 4
gpt4 key购买 nike

我想编写两个线程来递增和递减一个数字,以及一个确定两个数字何时相等的主线程。例如,一个数字从 0 开始,另一个数字从 10 开始……当它们都是 5 时,主线程应该识别它们相等并打印“它们相遇了!”。

在这段代码中,主线程不能不比较numupnumdown成功:

public class Number implements Runnable {
public static int numup = 0;
public static int numdown = 10;

public Number() {
}

public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();

while (true) {
if (numup == 5 && numdown == 5) {
System.out.println("Meet!");
System.exit(0);
}
}

}

public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {

numup++;
System.out.println(numup);

} else if (Thread.currentThread().getName().equals("down")) {

numdown--;
System.out.println(numdown);
}

try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}

}
}

失败的结果:

1
9
8
2
7
3
6
4
5
5
6
4
7
3
8
2
1
9

但是,当我让主线程 hibernate 几毫秒时,它起作用了:

public class Number implements Runnable {
public static int numup = 0;
public static int numdown = 10;

public Number() {
}

public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();

while (true) {

try {
Thread.sleep(10);
} catch (Exception e) {
System.out.println(Thread.currentThread().getName() + "was waked!");
}
if (numup == 5 && numdown == 5) {
System.out.println("They Meet!");
System.exit(0);
}
}

}

public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {

numup++;
System.out.println(numup);

} else if (Thread.currentThread().getName().equals("down")) {

numdown--;
System.out.println(numdown);
}

try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}

}
}

成功的结果:

1
9
2
8
3
7
4
6
5
5
They Meet!

为什么增加的延迟让它起作用?

最佳答案

这可能是因为 CPU 缓存。当 number 线程更新变量的值(从它的 CPU 缓存到主内存)时,相应主线程的 CPU 缓存可能还没有更新。

所以当主线程检查变量的值时,它仍然是旧值。

  1. 您可以使用 Volatile。或者
  2. 使用 AtomicInteger 进行这些操作。

可以引用这个link .

In a multithreaded application where the threads operate on non-volatile variables, each thread may copy variables from main memory into a CPU cache while working on them, for performance reasons. If your computer contains more than one CPU, each thread may run on a different CPU. That means, that each thread may copy the variables into the CPU cache of different CPUs.

With non-volatile variables there are no guarantees about when the Java Virtual Machine (JVM) reads data from main memory into CPU caches, or writes data from CPU caches to main memory.

volatile :

public static volatile int numup = 0;
public static volatile int numdown = 10;

原子整数:

import java.util.concurrent.atomic.AtomicInteger;

public class Number implements Runnable {
public static AtomicInteger numup = new AtomicInteger(0);
public static AtomicInteger numdown = new AtomicInteger(10);

public Number() {
}

public static void main(String args[]) {
Number number = new Number();
Thread T1 = new Thread(number, "up");
Thread T2 = new Thread(number, "down");
T1.start();
T2.start();

while (true) {
if (numup.get() == 5 && numdown.get() == 5) {
System.out.println("Meet!");
System.exit(0);
}
}
}

public void run() {
while (true) {
if (Thread.currentThread().getName().equals("up")) {

numup.incrementAndGet();
System.out.println(numup);

} else if (Thread.currentThread().getName().equals("down")) {

numdown.decrementAndGet();
System.out.println(numdown);
}

try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("wake!");
}
}

}
}

关于java - 为什么主线程不能比较两个由其他线程更新的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40689831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com