gpt4 book ai didi

java - 线程和静态变量

转载 作者:行者123 更新时间:2023-12-01 19:56:45 26 4
gpt4 key购买 nike

尝试理解这段代码。当我运行它时 - 输出将是Roger。 msg 不是静态变量并且在类级别因此应该打印 Moore 吗?

编辑:我也允许 sleep ,允许子线程运行它的进程。它还打印打印..。仍然没有变化

public class Test2 {
private static String msg = "Roger";

static {
new Thread(new Runnable() {
public void run() {
System.out.println("printing..");
msg += "Moore";
}
}).start();
}

static {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}

public static void main(String argv[]) {
System.out.println(msg);
}
}

最佳答案

Trying to wrap my head around this code. When I run this - the output will be Roger. Isn't msg a static variable and at a class level thus should print Moore?

正如其他人所指出的,这是一个竞争条件,但它比这个简单的答案更复杂。

EDIT : I've allowed a sleep too allow the child thread to run its course. It also prints printing... Still No Change

当一个类被初始化时,static代码在首先访问类的线程中执行——在本例中是主线程。所有其他线程必须等待初始化完成才能访问该类。这意味着后台线程实际上会停止并等待类初始化完成,然后才能执行 msg += "Moore"; 。然后是一场竞赛,看看该消息是否分配给 "Roger"并且后台线程可以附加到它之前 main打印它。即使有 msg场正在volatile ,种族仍然存在。您可以从JLS section 12.4.2 on Detailed Initialization Procedure中一窥整个过程的复杂性。 .

所以发生的事情大约是:

  1. 主线程初始化Test2类。
  2. msg首先初始化,因为它位于 static 之前 block 。
  3. 第一static执行 block , fork 后台线程。
  4. 第二个static执行 block ,执行 sleep()阻塞初始化线程。
  5. 后台线程开始运行(可能在上一步之前)。它会更新msg但该类已锁定,因为主线程正在 hibernate 并且尚未完成类初始化。后台线程必须等待。
  6. 主线程唤醒并完成初始化。
  7. 这会释放类上的 block ,从而允许后台线程继续。
  8. 与上一步同时,main被调用,这是一个竞争条件,看看 msg 是否可以在打印之前进行更新。

一般来说,在 static 中 fork 后台线程像这样的方法是非常不受欢迎的。放置 sleepstatic显然也不推荐使用 block。

关于java - 线程和静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19101537/

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