gpt4 book ai didi

java - java中的一个字段被多个线程异步(不一致)访问会发生什么?

转载 作者:行者123 更新时间:2023-12-01 19:00:05 25 4
gpt4 key购买 nike

我认为我对使用 synchronized 关键字来防止 java 中线程之间的不一致有相当的把握,但我不完全理解如果不使用该关键字会发生什么。

例如,我有一个由两个线程访问/修改的字段:

private String sharedString = "";

class OneThread extends Thread {

private Boolean mRunning = false;

public OneThread() {}

public synchronized setRunning(Boolean b) {
mRunning = b;
}

@Override
public void run() {
while (mRunning) {
// read or write to shared string
sharedString = "text from thread 1";
System.out.println("String seen from thread 1: " + sharedString);
super.run();
}
}
}

class AnotherThread extends Thread {

private Boolean mRunning = false;

public AnotherThread() {}

public synchronized setRunning(Boolean b) {
mRunning = b;
}

@Override
public void run() {
while (mRunning) {
// read or write to shared string
sharedString = "text from thread 2";
System.out.println("String seen from thread 2: " + sharedString);
super.run();
}
}
}

由于这两个线程都在不使用synchronized关键字的情况下访问和修改字段sharedString,因此我预计会出现不一致。我想知道的是实际发生了什么。在调试时,我在这种情况下仔细地检查了两个线程,并注意到即使一个线程暂停,它的状态也可能是“粘滞”的。

对于上面的示例,假设两个线程都在调试器中暂停。如果我单步执行其中一个线程并让另一个线程暂停,我希望它会像单线程应用程序一样运行。然而,很多时候在修改字段后,访问该字段的下一行会检索到“错误”值(与刚刚修改的值不一致的值)。

我知道这段代码不好..但我问这个问题是因为我希望有人能够提供一个答案,以便深入了解当多线程应用程序实现不佳时虚拟机中实际发生的情况。字段修改尝试失败的线程有任何影响吗?

如果在糟糕地实现多线程代码之后,我们只是处于“未定义”行为的领域,并且学习这种行为没有任何值(value),我对此表示同意......只是一个多线程菜鸟试图了解我在调试器中观察到的内容。

最佳答案

这是由于 Java 中跨线程同步的另一个关键功能:防止数据过时。作为 Java 内存模型的一部分,Java 线程可以缓存共享数据的值。除非在同步块(synchronized block)中访问共享可变数据或者将其标记为 volatile ,否则无法保证一个线程会看到另一个线程所做的更新。请参阅here了解更多信息。

关于java - java中的一个字段被多个线程异步(不一致)访问会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12556669/

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