ThreadPoolExecutor and finalization

Jason Mehrens jason_mehrens at
Thu Nov 2 16:13:33 UTC 2017


Executors.unconfigurableExecutorService was not modified on purpose because of the following case:


From: core-libs-dev <core-libs-dev-bounces at> on behalf of Peter Levart <peter.levart at>
Sent: Thursday, November 2, 2017 10:23 AM
To: David Holmes; Roger Riggs
Cc: core-libs-dev
Subject: Re: ThreadPoolExecutor and finalization


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) {
         protected void finalize() {

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

More information about the core-libs-dev mailing list