Hi,
I would think that the some part of the application or library would be
responsible for the (lifecycle of the)
executor that is being wrapped and it is not the responsibility of the
'view' to keep it alive.
$.02, Roger
On 11/2/2017 1:24 PM, Peter Levart wrote:
Hi Jason,
On 11/02/2017 05:13 PM, Jason Mehrens wrote:
Peter,
Executors.unconfigurableExecutorService was not modified on purpose
because of the following case:
http://cs.oswego.edu/pipermail/concurrency-interest/2006-March/002353.html
Jason
Oh, I see. The method is meant to provide a limited view over any
ExecutorService and there may be multiple views over same instance.
Regards, Peter
________________________________________
From: core-libs-dev <[email protected]> on
behalf of Peter Levart <[email protected]>
Sent: Thursday, November 2, 2017 10:23 AM
To: David Holmes; Roger Riggs
Cc: core-libs-dev
Subject: Re: ThreadPoolExecutor and finalization
Hi,
On 11/02/2017 01:47 PM, David Holmes wrote:
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.
I see there already is the following method in Executors:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new
LinkedBlockingQueue<Runnable>()));
}
private static class FinalizableDelegatedExecutorService
extends DelegatedExecutorService {
FinalizableDelegatedExecutorService(ExecutorService
executor) {
super(executor);
}
@SuppressWarnings("deprecation")
protected void finalize() {
super.shutdown();
}
}
If the same FinalizableDelegatedExecutorService was used also for the
following method:
/**
* Returns an object that delegates all defined {@link
* ExecutorService} methods to the given executor, but not any
* other methods that might otherwise be accessible using
* casts. This provides a way to safely "freeze" configuration and
* disallow tuning of a given concrete implementation.
* @param executor the underlying implementation
* @return an {@code ExecutorService} instance
* @throws NullPointerException if executor null
*/
public static ExecutorService
unconfigurableExecutorService(ExecutorService executor) {
if (executor == null)
throw new NullPointerException();
return new DelegatedExecutorService(executor);
}
...we would get such ExecutorService out of the box.
Regards, Peter