java-为什么主线程不能比较其他线程更新的两个变量?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-为什么主线程不能比较其他线程更新的两个变量?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3561字,纯文字阅读大概需要6分钟。
内容图文
我想编写两个增加数字并减少数字的线程,以及一个确定两个数字何时相等的主线程.例如,一个数字从0开始,另一个数字从10开始.当它们都为5时,主线程应认识到它们相等并打印“它们相遇!”.
在此代码中,主线程无法成功比较numup和numdown:
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
但是,当我使主线程休眠几毫秒时,它可以工作:
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缓存.当数字线程更新变量的值时(从它的CPU缓存到主内存),则相应主线程的CPU缓存可能尚未更新.
因此,当主线程检查变量的值时,它仍然是旧值.
>您可以使用Volatile.要么
>使用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.
易挥发的:
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-为什么主线程不能比较其他线程更新的两个变量?全部内容,希望文章能够帮你解决java-为什么主线程不能比较其他线程更新的两个变量?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。