2016-09-29 5 views
3

は、次のJavaコードジャワnewSingleThreadExecutorガベージコレクション

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

を考慮し、エグゼキュータが作成され、タスクR1とR2順次次々に実行されます。

私の質問です.2つのタスクr1とr2が終了するとどうなりますか?

私はエグゼキュータオブジェクトがガベージコレクションされると思いますが、シャットダウンするかどうかわかりません。エグゼキュータが実行のために新しいスレッドを作成する場合、このスレッドはリソースリークを引き起こしますか?

+1

ExecutorServiceを使用し、実行のためにタスクを送信した後にシャットダウンを呼び出すことができます。 ESはタスクが完了するまで待ってから終了します。 – Jacob

+0

コアスレッドがゼロの 'ThreadPoolExecutor'を使って、実行するタスクがないときにスレッドを再利用することもできます。 – Magnus

答えて

5

executorオブジェクトはガベージコレクトされると思いますが、シャットダウンするかどうかはわかりません。 木材下実際

Executors.newSingleThreadExecutor()

は、ガベージコレクションされるとき、それは自動的にシャットダウンされることを示すfinalizeshutdownを呼び出すFinalizableDelegatedExecutorServiceインスタンスを作成します。

しかし、あるバージョンから別のバージョンに変わる可能性のある実装の詳細なので、あまりにもそれに頼るのは良い考えではないと思います。予期せぬバグ。

+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のドキュメントから、私たちは「未使用のExecutorServiceのは その資源の再利用を可能にするためにシャットダウンしなければならない。」

を読むことができます

基本的に、エグゼキュータサービスを手動で終了する必要があります。 executorオブジェクト自体はガベージコレクトされますが、それは内部スレッドではありません。

+0

内部スレッドはありませんか?それは私を非常に驚かせる。 – erickson

+0

作成されたスレッドは、実行されるExecutorServiceへの参照を持ちます。これらが生きている限り、 'ExecutorService'はGCに適格ではありません。 –

+0

@ericksonドキュメントは、あなたのコードが 'ExecutorService'への参照を失った場合に特に起こることを約束していません。また、"リソース "を再利用したい場合は、シャットダウンするべきであると警告します。あなたのコードを「どこでも実行」させたいなら、おそらくjavadocが何を言っているのかを信じて、javadocが知らされていないものについて何も仮定しないでください。 –

0

オブジェクトは、そのオブジェクトがGCルートによって参照されていない場合にのみGCできます。 GCルートとは何ですか?最も一般的なものはSystemクラスと実行中のスレッドです。 ExecutorServiceは実行中のスレッドを作成して管理します。したがって、メソッド内でESが作成されても、ESには到達可能でGCではなくなります。

他にも言及しているとおり、ESをシャットダウンしてGCする必要があります。