소프트웨어를 작성할 때는 종종 인쇄 로그 기능을 사용해야하므로 프로젝트를 디버깅하고 배치하면 데이터를 분석하는 데 도움이됩니다. 그러나 Java의 기본 System.out.out.println () 메소드는 실제 프로젝트 개발에 거의 사용되지 않으며 FindBugs와 같은 코드 점검 도구조차 System.out.println ()을 사용하는 것이 버그라고 생각합니다.
Java의 초보자 인공물 인 System.out.println ()가 왜 실제 프로젝트 개발에 흩어질 것인가? 실제로, 신중하게 분석하는 한 많은 단점이 있습니다. 예를 들어, 제어되지 않으면 프로젝트가 시작된 후에는 모든 로그가 평소와 같이 인쇄되므로 운영 효율성이 줄어들거나 인쇄물이 구별되면 로그를 기록 할 수 없습니다 이 로그가 인쇄 된 범주를 구별합니다.
당신의 리더는 바보가 아닙니다. 그러나 리더는 꽤 좋으며 처음에는 다양한 기능을 갖춘 Niubi 로그 도구를 달성 할 수 없습니다.
이 수요는 당신에게는 어렵지 않습니다.
공개 클래스 {공개 결승전 = 1; system.out.println (msg);}} public void info (string msg) {if (info> = level) {system.out.println (msg);} public void ing msg) {if (error> = level) {system.out.println (msg);}}}
이 클래스를 통해 로그를 인쇄하고 인쇄 내용을 자유롭게 제어하기 위해 레벨 레벨 만 제어하면됩니다. 예를 들어, 프로젝트는 이제 개발 단계에 있으며 레벨이 디버그로 설정되어 모든 로그 정보가 인쇄됩니다. 프로젝트가 온라인 상태 인 경우 레벨을 정보로 설정하여 로그와 위의 레벨 로그 인쇄 만 볼 수 있습니다. 잘못된 로그를보고 싶다면 레벨을 오류로 설정할 수 있습니다. 그리고 개발 한 프로젝트가 클라이언트 버전이라면 로그를 인쇄하고 싶지 않으면 레벨을 아무것도 설정하지 못할 수 있습니다. 인쇄 할 때만 호출하면됩니다.
새로운 logutil (). 디버그 ( "Hello World!");
이 도구를 리더에게 소개 한 후에도 기다릴 수 없습니다. "좋아요, 모두 가이 도구로 로그를 인쇄 할 것입니다!"
그러나 지도자가 피드백을 제공하는 데 오래 걸리지 않았습니다. 그는이 도구를 사용하기 쉽지만 로그를 인쇄해야 할 때마다 새로운 로그 틸트를 생성해야한다고 말했습니다 이를 사용하여 단일 모드 구현.
당신은 당신의 리더가 매우 합리적이라고 생각하고 디자인 모드를 연습하기 위해이 기회를 활용하려고 노력하고 있으므로 다음 코드를 작성했습니다 (PS : 여기 코드는 혼자서 이루어지며주의를 기울이지 않았습니다. 나는 그것에주의를 기울이지 않았다.
공공 클래스 {개인 정적 로지 링 디버그 = 1; getInstance () {if (logutilinstance == null) {logutilinstance = new logutil ();} return logutilinstance;} public void debug (string g. {if (debug> = level) {system.out.println (msg);} } public void info (string msg) {if (info> = level) {system.out.println (msg);} public void error (string msg) {if (error> = level) {system .out );}} public static void main (String [] args) {logutil.getInstance ( "Hello World!");}}.
우선, Logutil의 생성자가 민영화되어 새로운 키워드를 사용하여 Logutil 인스턴스를 만들 수 없습니다. 그런 다음 slogutil private static 변수를 사용하여 인스턴스를 저장하고이 방법에서는 Slogutil이 비어 있으면 새로운 logutil 인스턴스를 사용할 수있는 것으로 결정됩니다. 직접 슬로 푸틸. 이렇게하면 메모리에 Logutil 인스턴스 만있을 수 있습니다. 단일 모드가 완료되었습니다! 현재 인쇄 로그의 코드는 다음과 같은 방식으로 변경해야합니다.
logutil.getInstance () 디버그 ( "Hello World");
당신은이 버전을 당신의 지도자에게 보여줍니다. 그는 그것을보고 웃으며 말했다.
당신은 의심으로 가득 차 있습니다. 단일면 모드가 이와 같이 실현되지 않습니까? 버그는 무엇입니까?
당신의 리더는 싱글 모드를 사용하는 것이이 클래스를 메모리에 하나의 인스턴스 만있게하는 것이지만, 멀티 스레드에서 로그를 인쇄하는 상황을 고려하십니까? 다음 코드에 표시된대로 :
public static logutil getinstance () {if (logutilinstance == null) {logutilinstance = new logutil ();} return logutilinstance;}
GetInstance 메소드를 동시에 실행하는 동시에 두 개의 스레드가 있으면 첫 번째 스레드는 두 번째 줄을 실행하지만 아직 IF 판단을 실행하지 않았습니다. 이런 식으로 두 개의 다른 인스턴스가 생성되어 싱글 모드가 실패합니다.
당신은 갑자기 알고 있지만, 당신은 즉시 솔루션을 생각합니다.
public synchronized static logutil getinstance () {if (logutilinstance == null) {logutilinstance = new logutil ();} return logutilinstance;}
이러한 방식으로, 하나의 스레드만이 GetInstance에서 코드를 동시에 실행할 수있게되며, 이는 두 인스턴스가 위에서 생성 할 상황을 효과적으로 해결합니다.
리더는 새 코드를 읽고 "음, 그렇습니다. 이것은 두 가지 인스턴스를 만들 수있는 상황을 해결하지만이 코드는 여전히 문제입니다."
당신은 긴장합니다. 왜 문제가 있습니까?
당신의 리더는 웃으며 : "긴장하지 말고, 이번에는 버그가 아니지만 성능 측면에서 최적화 될 수 있습니다. getinstance 메소드에 동기화 된 메소드를 추가하면 Getinstace로 이동할 때마다. 방법, 잠금 효과는 실제로이 작업의 효율성을 줄입니다.
먼저 메소드 문에서 동기화 된 키워드를 제거하고 메소드 본문에 추가하십시오.
public static logutil getInstance () {if (logutilinstance == null) {synchronized (logutil.class) {if (logutilinstance == null) {// 두 프로세스가 동일한 시간에 동일하게 첨부 될 수 있기 때문에 필요할 수 있습니다. 동시에 동시에. logutilinstance = 이전에 동기화 된 = new logutil ();}}} logutilinstance를 반환합니다.}}
코드가 변경되면 Slogutil이 초기화되지 않으면 세 번째 줄에 들어간 다음 동기 잠금을 추가합니다. Slogutil이 초기화 되 자마자 더 이상 세 번째 줄로 이동하지 않으므로 GetInstance 방법이 동기화 잠금의 영향을받지 않으며 효율은 어느 정도 향상됩니다.
당신은 도울 수는 없지만 존경합니다.이 방법은 정말 영리합니다.
당신의 리더는 즉시 겸손 해졌습니다. "이 방법을 Double-Check Locking이라고하지만 생각하지 않습니다. 인터넷에서 더 많은 정보를 확인할 수 있습니다."
사실, 나는 자바에서 배고픈 남자 모드를 사용하는 데 더 익숙합니다.
게으른 스타일의 특성은 하중이 지연됩니다.
배고픈 한 스타일의 특징은 처음에로드되므로 사용할 때 직접 반환 할 수 있다는 것입니다 (너무 많은 스레드 보안 문제를 고려할 필요가 없기 때문에 더 권장합니다. 물론 듀얼 잠금 장치. 동기화 문제를 해결하기 위해 언급)
배고픈 한 스타일로 로그 레코드를 구현하는 코드는 다음과 같습니다.
공개 클래스 {private final logutil () 공개 최종 정보 = 1; () {{{{public static logutil getInstance () {return logutilinstance;} public void debug (string msg) {if (debug> = level) {system.out.print ln (msg);} public void info (string msg) {if (info> = level) {system.out.println (msg);}} public void error (string msg) {if (error> = level) {system.out.println (msg);} public atic void main (string [] art) {logutil.getinstance () 디버그 ( "Hello World!");}}