版权声明:转载请注明链接 https://blog.csdn.net/weixin_38569499/article/details/87945896
最近在写代码的时候,写了一个奇怪的问题。我写了一个主函数,测试刚写一个方法,其中调用了Log4j的API去打印log,但是log打印不出来,检查配置文件也没有问题。代码如下:
public static void main(String[] args) {
Logger logger = LogManager.getLogger(“MAIN”);
String url = "http://******";
String expectedPath = "******";
try {
String actualPath = mappingUrlToBackupPath(yuyiguoUrl);
logger.info("actual path: " + actualPath);
assert expectedPath.equals(actualPath);
System.exit(0);
} catch (Exception e) {
logger.error(e);
System.exit(-1);
}
}
多番检查无果后,怀疑是System.exit导致的log4j打印日志的线程还没来得及把日志打印出来就被kill掉了。所以查看了一下System的源码和说明文档。
如下是System类中的exit方法的源码和说明文档:
/**
* Terminates the currently running Java Virtual Machine. The
* argument serves as a status code; by convention, a nonzero status
* code indicates abnormal termination.
* <p>
* This method calls the <code>exit</code> method in class
* <code>Runtime</code>. This method never returns normally.
* <p>
* The call <code>System.exit(n)</code> is effectively equivalent to
* the call:
* <blockquote><pre>
* Runtime.getRuntime().exit(n)
* </pre></blockquote>
*
* @param status exit status.
* @throws SecurityException
* if a security manager exists and its <code>checkExit</code>
* method doesn't allow exit with the specified status.
* @see java.lang.Runtime#exit(int)
*/
public static void exit(int status) {
Runtime.getRuntime().exit(status);
}
从源码可以看出,System.exit调用了Runtime的exit方法,关闭了整个运行环境。看说明文档也能发现,“Terminates the currently running Java Virtual Machine.”,直接关闭掉了整个虚拟机。可以判断,主线程在运行的过程中迅速执行到System.exit方法,此时log4j用于打印日志的线程还没有开始工作,但是System.exit被调用后,整个虚拟机都被关掉,log4j无法完成日志的打印。
在这里也顺便提一下,exit方法传入的参数,只有值为0的时候才是正常退出,参数status是任意非0值都表示程序非正常退出。