深入理解為什麼不要使用System.out.println()
關於專案中為什麼不要使用System.out.println()的解釋,網上有很多資料卻並不準確或者詳細,今天小星就其原因以及可能對專案造成的影響做深入剖析。
本篇文章氛圍三個 要點,原始碼解析、影響分析、程式碼演示。
原文出處:https://www.cofestar.com/blog/system-out-println.html
一、原始碼解析
開啟println的原始碼,看到println方法體中有synchronized,也就是有鎖的控制,換而言之就會出現阻塞的可能,後面我們會認為製造阻塞來演示。
如下圖:
開啟out原始碼,發現out用final static來修飾,也就是靜態變數,可以認為在單機jvm中該變數全域性唯一,如下圖:
二、影響分析
通過以上兩個圖,我們可以想到有這麼一種場景,在System.out.println()執行過程中,或因系統原因或者其它原因,導致在執行println的時候,發生了阻塞,那麼因此帶來的後果是,所有使用System.out.println()的地方,都會處於block狀態,甚至引發系統宕機等。
至於System.out.println()本身的效能問題,可以作為單純的效能優化來講,也是不建議使用,既然是深入分析,我們先看下嚴重的場景,這才是導致禁用Syste.out.println()的重要原因。
三、程式碼模擬
我們根據原始碼,模擬這麼一種場景,由於某種原因,System.out處於鎖定狀態,長時間沒有釋放,會引發什麼。
模擬步驟:
1、新建兩個執行緒:執行緒一和執行緒二
2、讓執行緒一和執行緒二執行三秒後,開始對System.out進行鎖定
3、檢視執行緒一和執行緒二在System.out鎖定時的列印情況及執行緒狀態
4、釋放System.out鎖,在此檢視執行緒一和執行緒二的執行情況
以下是測試程式碼:
此處執行邏輯是按照方才的說明步驟進行,執行緒中僅僅使用System.out.println進行列印,在System.out處於鎖定狀態時,檢視兩個執行緒是否會繼續列印
執行緒中每隔1.5秒列印一次。
我們執行列印程式,檢視控制檯日誌:
結論:
通過控制檯日誌可以看到,執行緒一和執行緒二在執行過程中,如果System.out處於鎖定時,兩個執行緒處於BLOCKED狀態,且不在進行列印,等待10秒System.out鎖釋放後,又開始重新執行列印。
所以說,生產上如果大量使用System.out.println(),將會對所有使用該語句的邏輯造成阻塞,影響不言而喻。