2016-09-29 4 views
3

은 실행 프로그램이 생성되어 다른 후 작업 R1 및 R2 순차적 하나를 수행하고, 다음 자바 코드자바 newSingleThreadExecutor 가비지 컬렉션

void doSomething(Runnable r1, Runnable r2){ 
    Executor executor = Executors.newSingleThreadExecutor(); 
    executor.execute(r1); 
    executor.execute(r2); 
} 

을 고려한다.

제 질문은 : 두 작업 r1과 r2가 종료되면 어떻게 될까요?

executor 개체가 가비지 수집 될 것이라고 가정하지만 종료할지 여부는 알지 못합니다. executor가 실행을위한 새로운 쓰레드를 생성한다면,이 쓰레드는 리소스 누출을 초래할 것인가?

+1

ExecutorService를 사용하고 실행을 위해 작업을 제출하면 shutdown을 호출 할 수 있습니다. ES는 작업이 완료 될 때까지 기다렸다가 종료됩니다. – Jacob

+0

코어 태스크가 0 인'ThreadPoolExecutor'를 사용해, 실행하는 태스크가없는 경우에 thread가 재생되도록 (듯이) 할 수도 있습니다. – Magnus

답변

5

Executor 개체가 가비지 수집 될 것이라고 가정하지만, 역시 종료 될지 여부는 알 수 없습니다. 나무 아래

사실

Executors.newSingleThreadExecutor() 가비지 수집 될 때 자동적으로 종료 될 것임을 나타내는 finalizeshutdown 호출하는 FinalizableDelegatedExecutorService 인스턴스를 생성한다.

그러나 나는 한 버전에서 다른 버전으로 변경 될 수있는 구현 세부 사항이기 때문에 너무 많이 의존하는 것이 좋지 않을 것이라고 생각합니다. 예기치 않은 버그.

ExecutorService의 문서에서
+0

FinalizableDelegatedExecutorService 인스턴스가 만들어 졌다는 사실에 대한 언급이 있습니까? – ichfarbstift

+0

예 여기 http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/concurrent/Executors.java#Executors.newSingleThreadExecutor%28%29 –

+1

@ ichfarbstift 코드입니다. 그러나 코드의 그 측면은 "계약에 의해"보장되지 않으므로 그것에 의존하지 마십시오. 'ExecutorService' 레퍼런스를 잃기 전에'shutdown()'을 호출하십시오. 그리고'shutdown()'이 호출 되었더라도, 이전에 제출 된 작업이 완료 될 때까지'ExecutorService'가 실행됩니다. – erickson

3

우리는

는 "사용되지 않는 ExecutorService를가 자원의 매립을 허용 종료해야합니다."읽을 수 있습니다

기본적으로 실행 프로그램 서비스를 수동으로 종료해야합니다. executor 객체 자체는 가비지 수집되지만 내부 스레드는 그렇지 않습니다.

+0

내부 스레드가되지 않습니까? 그것은 나를 매우 놀라게한다. – erickson

+0

생성 된 쓰레드는 실행중인'ExecutorService'에 대한 참조를 가지고 있습니다. 살아있는 한'ExecutorService'는 GC에 적합하지 않습니다. –

+0

@erickson 문서는 ExecutorService에 대한 참조를 잃어 버렸을 때 어떤 일이 일어날 것이라고 약속하지 않으며, "자원"을 회수하기를 원할 경우 종료해야한다고 경고합니다. 코드를 "어디서든"실행하려면 javadoc에서 말하는 내용을 믿어야하며 javadoc이 언급되지 않은 내용에 대해 아무 것도 가정하지 않아야합니다. –

0

개체는 GC 루트가 해당 개체를 참조하지 않는 경우에만 GC 할 수 있습니다. GC 루트 란 무엇입니까? 가장 일반적인 클래스는 System 클래스와 실행중인 스레드입니다. ExecutorService는 실행중인 스레드를 만들고 유지 관리하므로 ES가 메소드 내에서 작성 되더라도 ES는 계속 도달 할 수 있으며 GC가 아닙니다.

다른 언급처럼, GC를 수행하려면 ES를 종료해야합니다.