Why does the ExecutorService interface not implement AutoCloseable?

前端 未结 3 1737
北恋
北恋 2020-12-29 04:01

Failing to call shutdown() on a thread executor will result in a never terminating application.

Best practice to shut down the ExecutorService is this:

相关标签:
3条回答
  • 2020-12-29 04:42

    This is a mediocre workaround

    ExecutorService service = Executors.newSingleThreadExecutor();
    try (Closeable close = service::shutdown) {
    
    }
    

    Or, if the checked exception bothers you, you could write:

    interface MyCloseable extends AutoCloseable {
        void close();
    }
    

    And then

    ExecutorService service = Executors.newSingleThreadExecutor();
    try (MyCloseable close = service::shutdown) {
    
    }
    

    Of course, you must never ever put anything between the assignment and the try statement, nor use the service local variable after the try statement.

    Given the caveats, just use finally instead.

    0 讨论(0)
  • 2020-12-29 04:52

    That ExecutorService has actually two shutdown-related methods; based on the simple fact that both ways of shutting down a service make sense.

    Thus: how would you auto-close a service then? In a consistent manner that works for everybody?!

    So, the reasonable explanation in my eyes: you can't make an ExecutorService a AutoClosable because that service does not have a single "close" like operation; but two!

    And if you think you could make good use of such an auto-closing service, writing up your own implementation using "delegation" would be a 5 minute thing! Or probably 10 minutes, because you would create one version calling shutdown() as close operation; and one that does shutdownNow() instead.

    0 讨论(0)
  • 2020-12-29 04:54

    I don't see where AutoCloseable is that useful for an Executor. try-with-resources is for things that can be initialized, used, and released within the scope of a method. This works great for things like files, network connections, jdbc resources, etc., where they get opened, used, and cleaned up quickly. But an executor, especially a threadpool, is something you want available for a long time period, probably over the lifetime of the application, and will tend to get injected into things like singleton services, which can have a method that the DI framework knows to call on application shutdown to clean up the executor. This usage pattern works fine without try-with-resources.

    Also, a big motivator behind try-with-resources is making sure exceptions don't get masked. That's not a consideration so much with executors, all the exception-throwing will be happening in the tasks submitted to the executor, exception-masking is not an issue.

    0 讨论(0)
提交回复
热议问题