ThreadPoolExecutor and finalization
David Holmes
david.holmes at oracle.com
Thu Nov 2 12:47:25 UTC 2017
On 2/11/2017 7:26 PM, Peter Levart wrote:
> On 11/02/2017 03:34 AM, David Holmes wrote:
>> On 2/11/2017 3:46 AM, Peter Levart wrote:
>>> On 11/01/17 13:34, David Holmes wrote:
>>>> On 1/11/2017 10:20 PM, Peter Levart wrote:
>>>>> On 11/01/17 10:04, David Holmes wrote:
>>>>>> On 1/11/2017 6:16 PM, Peter Levart wrote:
>>>>>>> On 11/01/17 02:49, David Holmes wrote:
>>>>>>>> Hi Roger,
>>>>>>>>
>>>>>>>> On 31/10/2017 11:58 PM, Roger Riggs wrote:
>>>>>>>>> Hi Peter,
>>>>>>>>>
>>>>>>>>> Only native resources that do not map to the heap allocation/gc
>>>>>>>>> cycle need any kind
>>>>>>>>> of cleanup. I would work toward a model that encapsulates the
>>>>>>>>> reference to a native resource
>>>>>>>>> with a corresponding allocation/release mechanism as you've
>>>>>>>>> described here and in the
>>>>>>>>> thread on zip.
>>>>>>>>>
>>>>>>>>> For cleanup purposes, the independence of each resource may
>>>>>>>>> improve robustness
>>>>>>>>> by avoiding dependencies and opportunities for entanglements
>>>>>>>>> and bugs due to exceptions
>>>>>>>>> and other failures.
>>>>>>>>>
>>>>>>>>> In the case of TPE, the native resources are Threads, which
>>>>>>>>> keep running even if they are
>>>>>>>>> unreferenced and are kept referenced via ThreadGroups.
>>>>>>>>> I don't know the Executor code well enough to do more than
>>>>>>>>> speculate, but would suggest
>>>>>>>>> that a cleaner (or similar) should be registered for each thread .
>>>>>>>>
>>>>>>>> Threads are not native resources to be managed by Cleaners! A
>>>>>>>> live Thread can never be cleaned. A dead thread has nothing to
>>>>>>>> clean!
>>>>>>>
>>>>>>> Right, but an idle thread, waiting for a task that will never
>>>>>>> come since the only entry point for submitting tasks is not
>>>>>>> reachable (the pool), may be cleaned...
>>>>>>
>>>>>> cleaned? It can be interrupted if you know about it and find
>>>>>> locate it. But it will not be eligible for cleaning ala Cleaner as
>>>>>> it will always be strongly reachable.
>>>>>
>>>>> Ah I see what you meant before. Yes, tracking Thread object with a
>>>>> Cleaner does not have any sense. But tracking thread pool object
>>>>> with a Cleaner and cleaning (stopping) threads as a result makes
>>>>> sense...
>>>>
>>>> No, because live Threads will keep the thread pool strongly reachable.
>>>>
>>>> If you manage to structure things such that the Threads don't keep
>>>> the pool strongly reachable then you risk having the pool cleaned
>>>> while still actively in use.
>>>
>>> Pool is actively in use when it is still reachable. Only in that case
>>> can new tasks be submitted. When it is not reachable any more, no new
>>> tasks can be submitted and it can be shutdown():
>>>
>>> /**
>>> * Initiates an orderly shutdown in which previously submitted
>>> * tasks are executed, but no new tasks will be accepted...
>>
>> Didn't we already determine that a Cleaner can't call shutdown()
>> because that requires a strong reference it doesn't have?
>
> It can't call shutdown() on a tracked pool object, but it could do
> something that acted equivalently as shutdown().
>
>>
>> I think Doug already summed this up. The existing finalize() is
>> pointless because when it could be called there is nothing left to be
>> "cleaned up". There's no need for any use of Cleaner (even if it could
>> do anything useful).
>
> There's no need for finalize() or Cleaner in existing TPE as is, I
> agree. But there could be a thread pool that would self-shutdown when it
> is of no use any more (either using finalize() or Cleaner). For example,
> here is such pool:
>
> public class CleanableExecutorService implements ExecutorService {
> private final ThreadPoolExecutor tpe;
>
> public CleanableExecutorService(ThreadPoolExecutor tpe) {
> CleanerFactory.cleaner().register(this, tpe::shutdown);
> this.tpe = tpe;
> }
>
> // implement and delegate all ExecutorService methods to tpe...
> }
Ah I see - the old "extra level of indirection" solution. :) The Cleaner
keeps the tpe strongly reachable, but as soon as the holder class
becomes "unreachable" the Cleaner will shutdown the tpe.
Though if you plan on abandoning a TPE such that you can't shutdown
directly, then you may as well just configure it so all the threads
terminate and it will "self-clean".
Cheers,
David
> Regards, Peter
>
>>
>> David
>
More information about the core-libs-dev
mailing list