慎用System.out.println!!!

2019-10-24 23:26:44 浏览数 (1)

版权声明:本文为博主原创文章,遵循 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的代码。

后记

其实写文章的时候,老师还有一点小问题没有给出解答,童鞋们可以自己思考一下。

  1. System.out.println会输出到tomcat容器的catalina.out文件中吗?
  2. System.out.println在error级别的日志中,会输出日志吗?
  3. System.out.println在IDEA中的快捷键符号是啥?

0 人点赞