版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/linzhiqiang0316/article/details/102692496
初学者一般在开发中或者调试bug的时候,都会习惯性的使用System.out.println语句,输出到控制台中,观察数据是否正常。开发或者调试完毕,很可能就忘记删除,直接就发布到生产中去了。
问题导入
有童鞋会说,那有啥关系的,不就是控制台多打印一些日志嘛。那今天老师就和童鞋们分析一下,System.out.println输出语句对服务性能的影响。
场景设置
假如你的服务对性能要求极高,不能容忍请求响应时间过长,这个时候你的代码就不应该含有System.out.println语句,为什么这么说呢?下面看一下,老师给童鞋们做的一个小测试,代码如下所示:
代码语言:javascript复制public static void main(String[] args) {
long start1 = System.currentTimeMillis();
for(int i=0;i<100000;i ){
System.out.println("i:" i);
}
long end1 = System.currentTimeMillis();
System.out.println("有输出语句的耗时:" (end1-start1));
long start2 = System.currentTimeMillis();
for(int i=0;i<100000;i ){
}
long end2 = System.currentTimeMillis();
System.out.println("无输出语句的耗时:" (end2-start2));
}
有输出语句的耗时:408
无输出语句的耗时:0
从打印结果我们可以看到,循环10w次的打印时间需要耗时408毫秒,没有打印的循环几乎等于0毫秒。
原理分析
那这个时候问题就来了,为什么System.out.println语句会这么耗费性能呢?不要着急,我们看一下System.out.println语句的源码就知道答案了。
代码语言:javascript复制public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
从System.out.println的源代码,我们可以看到它在一开始就用synchronized同步锁给锁起来了,所以System.out.println是一个同步方法,在高并发的情况下,会严重影响性能。
总结
在日常开发或者调试的过程中,尽量使用log4j2或者logback这些异步的方法,进行日志的统一收集,禁止使用System.out.println。项目上线前也要进行全局搜索,防止有人误提交带有System.out.println的代码。
后记
其实写文章的时候,老师还有一点小问题没有给出解答,童鞋们可以自己思考一下。
- System.out.println会输出到tomcat容器的catalina.out文件中吗?
- System.out.println在error级别的日志中,会输出日志吗?
- System.out.println在IDEA中的快捷键符号是啥?