初學者一般在開發中或者調試bug的時候,都會習慣性的使用System.out.println語句,輸出到控制檯中,觀察數據是否正常。開發或者調試完畢,很可能就忘記刪除,直接就發佈到生產中去了。
問題導入
有童鞋會說,那有啥關係的,不就是控制檯多打印一些日誌嘛。那今天老師就和童鞋們分析一下,System.out.println輸出語句對服務性能的影響。
場景設置
假如你的服務對性能要求極高,不能容忍請求響應時間過長,這個時候你的代碼就不應該含有System.out.println語句,爲什麼這麼說呢?下面看一下,老師給童鞋們做的一個小測試,代碼如下所示:
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語句的源碼就知道答案了。
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中的快捷鍵符號是啥?
想要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裏等你哦~
林老師帶你學編程:https://wolzq.com