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...
}
Regards, Peter
David