ThreadPoolExecutor and finalization

David Holmes david.holmes at oracle.com
Tue Oct 31 08:55:31 UTC 2017


Hi Peter,

cc'ing Doug Lea

On 31/10/2017 6:25 PM, Peter Levart wrote:
> Hi David,
> 
> On 10/31/17 08:45, David Holmes wrote:
>>>> The docs for TPE cover this in detail: [1]
>>>>
>>>> Finalization
>>>>     A pool that is no longer referenced in a program AND has no 
>>>> remaining threads will be shutdown automatically. If you would like 
>>>> to ensure that unreferenced pools are reclaimed even if users forget 
>>>> to call shutdown(), then you must arrange that unused threads 
>>>> eventually die, by setting appropriate keep-alive times, using a 
>>>> lower bound of zero core threads and/or setting 
>>>> allowCoreThreadTimeOut(boolean).
>>>
>>> I'm trying to understand the purpose of finalize() in TPE, but can't. 
>>> I'm surely missing something. If the pool is no longer referenced AND 
>>> there are no active threads, what is there left to shutdown() 
>>> actually? All that remains is garbage that will eventually be GCed.
>>
>> Ummmmm .... I'm going to have to do some archaeology here ...
>>
>> David
> 
> I can imagine a thread pool where worker threads, while idling, don't 
> have a reference to the pool so the pool can shutdown() itself when:
> 
> - the pool is no longer referenced AND
> - there is no worker thread executing a task (i.e. all worker threads 
> are idle)
> 
> In such state, the pool is not reachable and may be shutdown.
> 
> But it seems that TPE is not such a pool.

Right. The TPE has a set of Workers (nested class) and each Worker has a 
Thread. The Thread executes the code of the Worker, so unless we hit the 
classic finalize problem of "this" being elided in a running method 
allowing the current object to get collected, then in theory any live 
worker threads should keep the whole TPE reachable.

In 2006 we added the docs about it being unreferenced and no remaining 
threads - which I guess is a necessary condition for finalization to now 
occur. But as you noted at that point shutdown() is pretty much a no-op.

Maybe Doug (cc'd) can recall the gory details. :)

Cheers,
David

> Regards, Peter
> 
>>
>>> Regards, Peter
>>>
>>>>
>>>> David
>>>> -----
>>>>
>>>> [1] 
>>>> https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/ThreadPoolExecutor.html 
>>>
> 


More information about the core-libs-dev mailing list