Re: ThreadPoolExecutor - cancel rejected tasks with Discard*Policy?
Viktor Klang via Concurrency-interest <[email protected]>
| Newsgroups | gmane.comp.java.jsr.166-concurrency |
|---|---|
| Message-ID | <CANPzfU_uf6qr5SoJDM-BV5HAbc3EnYObOs4SLgg5NXpXRdPp5g@mail.gmail.com> |
The real downside with CallerRunsPolicy is that it discards Runnables when the pool is shutting down, which means that in all cases where there might be a race condition between shutting down and submitting tasks, they may not get run at all :S On Wed, Feb 12, 2020 at 10:03 AM Petr Janeček via Concurrency-interest < [email protected]> wrote: > Hello, > > I'm sorry to open a new thread on something I feel must have been > discussed before, > I did not find any previous mention. > > Imagine this: > > ```java > // Note the DiscardPolicy > ExecutorService executor = new ThreadPoolExecutor( > 1, 1, > 1, TimeUnit.MINUTES, > new ArrayBlockingQueue<>(1), > new ThreadPoolExecutor.DiscardPolicy() > ); > > Runnable task = () -> Uninterruptibles.sleepUninterruptibly(1, > TimeUnit.SECONDS); > executor.submit(task); > executor.submit(task); > // The following task will get rejected and discarded by the pool: > executor.submit(task).get(); > ``` > > The code above will block forever, the `get()` call never returns. The task > had been rejected, but the returned Future is not cancelled, will never > run, > and therefore will never be completed in any way. There's no way I'm aware > of to know the returned Future had been rejected. > > This was very confusing and unexpected to me, I definitely expected the > policy > to cancel the task. Note that this only happens with the Discard* policies > because the AbortPolicy throws and never returns a broken Future to the > user, > while the CallerRunsPolicy returns a runnable Future. > > I'd like to open a discussion around a few possible naive approaches to > ease > the pain of future developers who get similarly caught by surprise: > > 1. Change the Discard*Policy to cancel the task. I did not find any place > where this would break any existing contracts. That said, obviously such > a change changes the behaviour in a significant way, and so it might not be > the way to go. > > 2. Introduce a DiscardAndCancelPolicy. Yes, writing such a policy is > trivial > and anybody can do it if he needs it. The problem is that this is so > obscure > that I cannot imagine many people do this right away. Discoverability is > very > important here, and having an extra policy would tip people off. > > 3. Change the Discard*Policie's JavaDoc in a way it is clear that it does > not > play with ExecutorService.submit() very well. > > 4. All of the above, or some more complex solution? > > Thank you, > Petr Janeček > _______________________________________________ > Concurrency-interest mailing list > [email protected] > http://cs.oswego.edu/mailman/listinfo/concurrency-interest > -- Cheers, √ _______________________________________________ Concurrency-interest mailing list [email protected] http://cs.oswego.edu/mailman/listinfo/concurrency-interest