스레드 풀을 왜 써요?

1. 스레드 탱크의 다중 스레드를 사용하는 이유는 다중 핵 프로세서의 계산 능력을 최대한 발휘하고 시스템의 토출량과 성능을 향상시킬 수 있기 때문이다.그러나 함부로 라인을 사용하면 시스템 성능에 오히려 불리한 영향을 미친다.
예컨대
 new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

이렇게 직접 라인을 만듭니다. 간단한 응용 프로그램에서 문제가 없을 것 같아서 라인을 만듭니다.run () 방법이 끝난 후에 자동으로 이 라인을 회수합니다.그러나 실제 시스템에서 업무 상황 때문에 많은 라인을 열었을 수도 있고 라인의 수량이 얼마나 많을 때 오히려 cpu와 메모리 자원을 소모할 수도 있다.
예를 들어 라인을 만들고 소각하는 데도 시간이 필요하다. 만약에 라인을 만들고 소각하는 시간이 라인이 실행하는 시간보다 훨씬 많으면 오히려 얻는 것보다 잃는 것이 많다.그 다음으로 스레드도 메모리 공간을 차지해야 한다. 대량의 스레드는 귀중한 메모리 자원을 차지하고 out of memory 이상을 초래할 수 있다.또한 대량의 라인 회수도 GC에 큰 압력을 가져와 GC의 정지 시간을 연장할 수 있다.
예를 들면 10000000개 라인을 켰을 때.
 for (int i = 0; i <10000000; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

Exception in thread “main” java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:717) at demo4.ThreadDemo.main(ThreadDemo.java:17)
그러니까 이런 일은 절대 경계해야 돼요.
마지막으로 대량의 라인도 cpu의 자원을 점령할 것이다. cpu는 끊임없이 각 라인의 상하문 전환 중에 오히려 라인이 실행될 때 처리해야 할 임무를 처리할 시간이 없다.
따라서 빈번한 루트 생성과 소각을 피하기 위해 생성된 루트를 복용시키기 위해 루트 탱크의 개념이 생겼다.스레드 탱크에서 일부 활발한 스레드를 유지할 수 있습니다. 필요하면 스레드 탱크에 가서 스레드를 가져와서 사용하고 다 사용하면 스레드 탱크에 돌려줍니다. 스레드를 만들고 없애는 비용을 면하고 스레드 탱크도 스레드의 수량에 일정한 제한이 있습니다.
예를 들어 방금 코드는 스레드 탱크를 사용하여 스레드를 구축한다
ExecutorService executorService= Executors.newFixedThreadPool(10);
        for (int i = 0; i <10000000; i++) {
           Thread t= new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("    ");
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });

            executorService.submit(t);
        }

    }

매번 10개의 라인만 활성화되고 나머지는 라인 탱크에 있는 작업 대기열에 놓이기 때문에 out of memory 오류가 발생하지 않습니다.이것은 스레드 탱크를 사용하는 장점 중의 하나다.
그러나 스레드 탱크도 여러 가지로 나뉘는데 상황에 따라 사용해야 한다. newFixedThreadPool 내부의 작업 대기열은 무계 대기열이고 작업이 너무 많으면 메모리가 부족할 수 있다.

좋은 웹페이지 즐겨찾기