java 최적화의 단일 모델 최적화

9155 단어
이 분류된 문장은 모두 필자가 (갈일명)라는 책을 읽은 것에 의해 이해되었다.만약 부족한 것이 있으면, 사내들에게 조언을 부탁합니다.

단일 모드


단일 모드로 만든 대상은 시스템에서 하나의 예시만 생성될 수 있도록 합니다.주로 다음과 같은 두 가지 장점이 있다.자주 사용하는 대상에 대해서는 대상을 만드는 데 걸리는 시간을 생략할 수 있습니다.new 작업 횟수가 줄어들기 때문에 시스템 메모리에 대한 사용 빈도도 낮아진다.GC의 압력을 경감시킬 것이다.GC 정지 시간을 단축하다.

단일 예제 모드 만들기

public class SingleClassDemo {

    //     
    public static SingleClassDemo sSingleClassDemo = new SingleClassDemo();

    private SingleClassDemo() {
        System.out.println(" ");
    }


    public static SingleClassDemo getInstance() {
        return sSingleClassDemo;
    }


    //  
    //public static String otherMethod() {
    //    return "otherMethod otherMethod!";
    //}

}

/**
*	 
*/
public class TestSingleClassDemo {
    @Test
    public void testInstance() {

        SingleClassDemo instance = SingleClassDemo.getInstance();
        System.out.println(instance);
        // :   top.wintp.demo.SingleClassDemo@50486d1d
    }
}
 

예를 들어 상술한 코드는 단례 모델의 간단한 실현 방식이다.우리의 이런 실현 방식에 무슨 문제가 있을지 생각해 봐라.이 클래스에 다른 정적 방법이 존재할 때, 우리는 이 클래스의 다른 정적 방법을 직접 호출하고, 이 클래스의 대상을 만들 것이다. 이것은 우리가 얻고 싶지 않은 결과이다
호출 예:
public class TestSingleClassDemo {
    @Test
    public void testInstance() {
        // ,   
        String string = SingleClassDemo.otherMethod();
        System.out.println(string);
        // :         cotherMethod otherMethod!
    }
}

단일 모드 최적화 1 (마운트 게으름 모드)


단례 대상을 만들 시기를 수정하고 필요할 때 다시 대상을 만듭니다.

public class LazSingleClassDemo {

    private static LazSingleClassDemo mLazSingleClassDemo = null;

    private LazSingleClassDemo() {
        System.out.println(" ");
    }

    public static LazSingleClassDemo getmLazSingleClassDemo() {

        if (mLazSingleClassDemo == null) {
            mLazSingleClassDemo = new LazSingleClassDemo();
        }

        return mLazSingleClassDemo;
    }

    public static String otherMehod() {

        return "otherMehod otherMehod";
    }
}



public class TestSingleClassDemo {
    @Test
    public void testInstance() {

        //     
        //   
        String string = LazSingleClassDemo.otherMehod();
        System.out.println(string);
        // :otherMehod otherMehod
    }
}


다중 스레드가 병발할 때, 게으름 로드 모드가 나타날 수 있습니다. 현재 스레드 검출은null이고, 두 번째 스레드 검출은null이며, 두 대상을 동시에 만드는 경우입니다.그것은 단례의 원칙에 위배된다.
호출 예:

public class TestSingleClassDemo {
    @Test
    public void testInstance() {
        //     
        new Thread("t1") {
            public void run() {
                LazSingleClassDemo lazSingleClassDemo = LazSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(lazSingleClassDemo);
            }
        }.start();
        new Thread("t2") {
            public void run() {
                LazSingleClassDemo lazSingleClassDemo = LazSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(lazSingleClassDemo);
            }
        }.start();
        new Thread("t3") {
            public void run() {
                LazSingleClassDemo lazSingleClassDemo = LazSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(lazSingleClassDemo);
            }
        }.start();
        new Thread("t4") {
            public void run() {
                LazSingleClassDemo lazSingleClassDemo = LazSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(lazSingleClassDemo);
            }
        }.start();

        new Thread("t5") {
            public void run() {
                LazSingleClassDemo lazSingleClassDemo = LazSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(lazSingleClassDemo);
            }
        }.start();


        /*
		 :
		
         
         
        t2
        top.wintp.demo.LazSingleClassDemo@475f260c
        t1
        top.wintp.demo.LazSingleClassDemo@55b9171e
        t3
        top.wintp.demo.LazSingleClassDemo@475f260c
        t4
        top.wintp.demo.LazSingleClassDemo@475f260c
        t5
        top.wintp.demo.LazSingleClassDemo@475f260c
         */
    }
}


단일 모드 최적화 2 (게으름 모드 라인 병발 문제)


동기화 방법을 사용하여 여러 라인이 병발하는 것을 피하다.

public class LazSingleSyncClassDemo {

    private static LazSingleSyncClassDemo mLazSingleClassDemo = null;

    private LazSingleSyncClassDemo() {
        System.out.println(" ");
    }

	// synchronized  
    public static synchronized LazSingleSyncClassDemo getmLazSingleClassDemo() {

        if (mLazSingleClassDemo == null) {
            mLazSingleClassDemo = new LazSingleSyncClassDemo();
        }

        return mLazSingleClassDemo;
    }

    public static String otherMethod() {

        return "otherMethod otherMethod";
    }
}


위 코드와 같이 다시 다중 스레드를 호출하면 여러 대상을 만드는 결과가 나타나지 않고 스레드가 안전하다는 것은 성능이 떨어지는 것을 피할 수 없다.다음은 스레드 동기화와 스레드가 다른 테스트 프로그램의 실행 시간입니다.

public class TestSingleClassDemo {
    @Test
    public void testInstance() {
        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            LazSingleClassDemo lazSingleClassDemo = LazSingleClassDemo.getmLazSingleClassDemo();
        }
        long endTime = System.currentTimeMillis();

        System.out.println(endTime - beginTime);
        //     :    2


        beginTime = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            LazSingleSyncClassDemo lazSingleClassDemo = LazSingleSyncClassDemo.getmLazSingleClassDemo();
        }
        endTime = System.currentTimeMillis();

        System.out.println(endTime - beginTime);
        //     :    5

    }
}



단일 모드 최적화 3(정적 내부 클래스로 최적화)


public class EndSingleClassDemo {

    private static EndSingleClassDemo mLazSingleClassDemo = null;

    private EndSingleClassDemo() {
        System.out.println(" ");
    }


    /**
     *  
     */
    private static class EndSingleClassDemoHolder {
        private static EndSingleClassDemo mLazSingleClassDemo = new EndSingleClassDemo();
    }

    public static EndSingleClassDemo getmLazSingleClassDemo() {

        return EndSingleClassDemoHolder.mLazSingleClassDemo;
    }

    public static String otherMehod() {

        return "otherMehod otherMehod";
    }
}


public class TestSingleClassDemo {
    @Test
    public void testInstance() {
        new Thread("t1") {
            public void run() {
                EndSingleClassDemo endSingleClassDemo = EndSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(endSingleClassDemo);
            }
        }.start();
        new Thread("t2") {
            public void run() {
                EndSingleClassDemo endSingleClassDemo = EndSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(endSingleClassDemo);
            }
        }.start();
        new Thread("t3") {
            public void run() {
                EndSingleClassDemo endSingleClassDemo = EndSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(endSingleClassDemo);
            }
        }.start();
        new Thread("t4") {
            public void run() {
                EndSingleClassDemo endSingleClassDemo = EndSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(endSingleClassDemo);
            }
        }.start();
        new Thread("t5") {
            public void run() {
                EndSingleClassDemo endSingleClassDemo = EndSingleClassDemo.getmLazSingleClassDemo();
                System.out.println(this.getName());
                System.out.println(endSingleClassDemo);
            }
        }.start();


        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 100000; i++) {
            EndSingleClassDemo endSingleClassDemo = EndSingleClassDemo.getmLazSingleClassDemo();
        }
        long endTime = System.currentTimeMillis();

        System.out.println(" :" + (endTime - beginTime));
       
        /*
         :
        
         
        t1
        t2
        t3
        top.wintp.demo.EndSingleClassDemo@4dbb3e34
        top.wintp.demo.EndSingleClassDemo@4dbb3e34
        top.wintp.demo.EndSingleClassDemo@4dbb3e34
        t4
        top.wintp.demo.EndSingleClassDemo@4dbb3e34
        t5
        top.wintp.demo.EndSingleClassDemo@4dbb3e34
         :1
         */

    }
}



우수한 프로그래머는 프로그램을 작성할 줄 알아야 할 뿐만 아니라, 고품질의 프로그램을 작성하는 것도 배워야 한다.일은 어렵지만 하면 된다.길이 비록 멀지만, 걸어가면 도착한다.

좋은 웹페이지 즐겨찾기