Java 在单线程程序中执行两次代码块
在我下面的程序中,我观察到Java 在单线程程序中执行两次代码块,java,Java,在我下面的程序中,我观察到score变量的值是预期值的两倍(999000而不是499500)。仔细观察它表明,即使在第一次调用后,标志被设置为true,计算也会进行两次。知道这里出了什么问题吗?该程序是单线程的。实际计算涉及调用RESTAPI,但出于测试目的,我已将其删除 public class DataClient { public static void main(String[] args) { System.out.println(CalculationCache.getS
score
变量的值是预期值的两倍(999000而不是499500)。仔细观察它表明,即使在第一次调用后,标志
被设置为true,计算也会进行两次。知道这里出了什么问题吗?该程序是单线程的。实际计算涉及调用RESTAPI,但出于测试目的,我已将其删除
public class DataClient {
public static void main(String[] args) {
System.out.println(CalculationCache.getScore());
}
}
class CalculationCache{
static{
computeScore();
}
private static int score;
public static int getScore() {
computeScore();
return score;
}
private static boolean flag=false;
static void computeScore(){
if(!flag) {
//calculate the score
for (int i = 0; i < 1000; i++) {
score = score + i;
flag = true;
}
}
}
}
公共类数据客户端{
公共静态void main(字符串[]args){
System.out.println(CalculationCache.getScore());
}
}
类计算缓存{
静止的{
computeScore();
}
私人静态智力得分;
公共静态int getScore(){
computeScore();
返回分数;
}
私有静态布尔标志=false;
静态void computeScore(){
如果(!标志){
//计算分数
对于(int i=0;i<1000;i++){
分数=分数+i;
flag=true;
}
}
}
}
该问题是由于类初始化的顺序造成的。静态初始值设定项按其定义的顺序执行。变量标志
仅在调用computeScore()
后初始化。因此,当第二次调用该方法时,flag
将为false
。您可能想要摆脱静态块
static{
computeScore();
}
如果您想要延迟初始化 这似乎是一个直接查看Java编译器生成的字节码可能非常有用的问题。@HovercraftFullOfEels为什么?关于初始化和静态块的简单规则就足够了。@Jean BaptisteYunès:如果只是在操作中查看这些规则,那么变量标志只有在调用computeScore()之后才初始化,这是不正确的,因为它会破坏java关于初始化的规则。第一次调用computeScore时,实际上标志默认初始化为false,然后在第二次调用时静态初始化为false。@chattambigeek Upvote/如果您认为有帮助,请接受答案。