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 <core-libs-dev-bounces@openjdk.java.net> on behalf of Peter Levart <peter.levart@gmail.com> 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