public static void main(String[] args) throws IOException {
// new fetchEmailID().fetchIDs();
new UserInputAndDefaulValues().validateUserInputAndDefaultValues();
while(!UserInputAndDefaulValues.start_mailing_flag)
{
//System.out.println(UserInputAndDefaulValues.start_mailing_flag);
}
MainExecutor.main_executor();
}
当我取消注释时
//System.out.println(UserInputAndDefaulValues.start_mailing_flag);
while循环中的条件正常工作,while循环在false条件下结束。但是当我评论它时,循环进入无限循环,即使它应该逃脱。为什么这种行为以及只有一个输出语句?
答案 0 :(得分:6)
首先,您的代码未正确同步。换句话说,它在start_mailing_flag
上包含数据竞赛。
现在,方法PrintStream#println
为synchronized
,因此调用它会强制JIT编译器避免对相关代码进行某些优化(即提升)。一旦删除该语句,效果就会消失。
总而言之,当您取消注释println
时,您的代码将通过纯粹的机会运行,并且作为调用synchronized
方法的副作用。它仍然像以前一样不安全。
答案 1 :(得分:5)
我猜你改变了另一个线程中的start_mailing_flag
(否则,难怪循环会永远发生)。
编译器优化此类情况并在第一次之后删除条件检查。它将代码更改为:
if (!UserInputAndDefaulValues.start_mailing_flag) {
while(true)
{
//System.out.println(UserInputAndDefaulValues.start_mailing_flag);
}
}
您需要将start_mailing_flag
定义为volatile
:
public class UserInputAndDefaulValues {
public static volatile boolean start_mailing_flag;
.....
}