JDK-6277663 : Improve extensibility of thread pools
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2005-05-28
  • Updated: 2017-05-16
  • Resolved: 2005-09-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b51Fixed
Description
Improve extensibility of ScheduledThreadPoolExecutor and AbstractExecutorService

Users want the flexibility to both:
- create their own thread pool implementation, while reusing
  ThreadPoolExecutor or AbstractExecutorService
- create their own Future implementation, possibly reusing
  FutureTask

Practice has shown that the current implementations do not provide
enough hooks to allow users to do this.

###@###.### 2005-05-28 00:20:10 GMT
###@###.### 2005-06-11 23:29:12 GMT

Comments
SUGGESTED FIX --- /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/package.html 2005-05-20 20:16:07.368079000 -0700 +++ /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/package.html 2005-05-23 19:59:26.784867000 -0700 @@ -31,13 +31,15 @@ asynchronous task execution framework. An ExecutorService manages queuing and scheduling of tasks, and allows controlled shutdown. The {@link java.util.concurrent.ScheduledExecutorService} subinterface -adds support for delayed and periodic task execution. +and associated interfaces add support for delayed and periodic task execution. ExecutorServices provide methods arranging asynchronous execution of any function expressed as {@link java.util.concurrent.Callable}, the result-bearing analog of {@link java.lang.Runnable}. A {@link java.util.concurrent.Future} returns the results of a function, allows determination of whether execution has completed, and provides a means to -cancel execution. +cancel execution. A {@link java.util.concurrent.RunnableFuture} is +a Future that possesses a <tt>run</tt> method that upon execution, +sets its results. <p> --- /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/ScheduledThreadPoolExecutor.java 2005-06-11 14:54:08.296069000 -0700 +++ /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/ScheduledThreadPoolExecutor.java 2005-05-22 17:56:53.694189000 -0700 @@ -6,7 +6,6 @@ */ package java.util.concurrent; -import java.util.concurrent.*; // for javadoc import java.util.concurrent.atomic.*; import java.util.*; @@ -30,6 +29,30 @@ * <tt>corePoolSize</tt> threads and an unbounded queue, adjustments * to <tt>maximumPoolSize</tt> have no useful effect. * + * <p>This class supports protected extension method + * <tt>decorateTask</tt> (one version each for <tt>Runnable</tt> and + * <tt>Callable</tt>) that can be used to customize the concrete task + * types used to execute commands. By default, + * a <tt>ScheduledThreadPoolExecutor</tt> uses + * a task type extending {@link FutureTask}. However, this may + * be modified or replaced using subclasses of the form: + * <pre> + * public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor { + * + * static class CustomTask&lt;V&gt; implements RunnableScheduledFuture&lt;V&gt; { ... } + * + * protected &lt;V&gt; RunnableScheduledFuture&lt;V&gt; decorateTask( + * Runnable r, RunnableScheduledFuture&lt;V&gt; task) { + * return new CustomTask&lt;V&gt;(r, task); + * } + * + * protected &lt;V&gt; RunnableScheduledFuture&lt;V&gt; decorateTask( + * Callable&lt;V;gt; c, RunnableScheduledFuture&lt;V&gt; task) { + * return new CustomTask&lt;V&gt;(c, task); + * } + * // ... add constructors, etc. + * } + * </pre> * @since 1.5 * @author Doug Lea */ @@ -132,7 +155,7 @@ * Returns true if this is a periodic (not a one-shot) action. * @return true if periodic */ - boolean isPeriodic() { + public boolean isPeriodic() { return period != 0; } /** + * Modify or replace the task used to execute a runnable. + * This method can be used to override the concrete + * class used for managing internal tasks. + * The default implementation simply returns the given + * task. + * + * @param runnable the submitted Runnable + * @param task the task created to execute the runnable + * @return a task that can execute the runnable + * @since 1.6 + */ + protected <V> RunnableScheduledFuture<V> decorateTask( + Runnable runnable, RunnableScheduledFuture<V> task) { + return task; + } + + /** + * Modify or replace the task used to execute a callable. + * This method can be used to override the concrete + * class used for managing internal tasks. + * The default implementation simply returns the given + * task. + * + * @param callable the submitted Callable + * @param task the task created to execute the callable + * @return a task that can execute the callable + * @since 1.6 + */ + protected <V> RunnableScheduledFuture<V> decorateTask( + Callable<V> callable, RunnableScheduledFuture<V> task) { + return task; + } + + /** * Creates a new ScheduledThreadPoolExecutor with the given core * pool size. * --- /u/martin/ws/jsr166/src/share/classes/java/util/concurrent/AbstractExecutorService.java 2005-06-11 15:55:37.002266000 -0700 +++ /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/AbstractExecutorService.java 2005-05-20 20:09:43.203271000 -0700 @@ -10,38 +10,84 @@ import java.util.*; /** - * Provides default implementations of {@link ExecutorService} + * Provides default implementation of {@link ExecutorService} * execution methods. This class implements the <tt>submit</tt>, - * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using the default - * {@link FutureTask} class provided in this package. For example, + * <tt>invokeAny</tt> and <tt>invokeAll</tt> methods using a + * {@link RunnableFuture} returned by <tt>newTaskFor</tt>, which defaults + * to the {@link FutureTask} class provided in this package. For example, * the implementation of <tt>submit(Runnable)</tt> creates an - * associated <tt>FutureTask</tt> that is executed and - * returned. Subclasses overriding these methods to use different - * {@link Future} implementations should do so consistently for each - * of these methods. + * associated <tt>RunnableFuture</tt> that is executed and + * returned. Subclasses may override the <tt>newTaskFor</tt> methods + * to return other <tt>RunnableFuture</tt> implementations than + * <tt>FutureTask</tt>. * + * <p> <b>Extension example</b>. Here is a sketch of a class + * that customizes {@link ThreadPoolExecutor} to use + * a <tt>CustomTask</tt> class instead of the default <tt>FutureTask</tt>: + * <pre> + * public class CustomThreadPoolExecutor extends ThreadPoolExecutor { + * + * static class CustomTask&lt;V&gt; implements RunnableFuture&lt;V&gt; {...} + * + * protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Callable&lt;V&gt; c) { + * return new CustomTask&lt;V&gt;(c); + * } + * protected &lt;V&gt; RunnableFuture&lt;V&gt; newTaskFor(Runnable r, V v) { + * return new CustomTask&lt;V&gt;(r, v); + * } + * // ... add constructors, etc. + * } + * </pre> * @since 1.5 * @author Doug Lea */ public abstract class AbstractExecutorService implements ExecutorService { + /** + * Returns a <tt>RunnableFuture</tt> for the given runnable and default + * value. + * @param runnable the runnable task being wrapped + * @param value the default value for the returned future + * @return a <tt>RunnableFuture</tt> which when run will run the + * underlying runnable and which, as a <tt>Future</tt>, will yield + * the given value as its result and provide for cancellation of + * the underlying task. + * @since 1.6 + */ + protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { + return new FutureTask<T>(runnable, value); + } + + /** + * Returns a <tt>RunnableFuture</tt> for the given callable task. + * @param callable the callable task being wrapped + * @return a <tt>RunnableFuture</tt> which when run will call the + * underlying callable and which, as a <tt>Future</tt>, will yield + * the callable's result as its result and provide for + * cancellation of the underlying task. + * @since 1.6 + */ + protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { + return new FutureTask<T>(callable); + } + --- /dev/null 2005-06-11 15:51:45.000000000 -0700 +++ /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/RunnableFuture.java 2005-05-23 19:59:26.631603000 -0700 @@ -0,0 +1,28 @@ +package java.util.concurrent; + +/** + * A {@link Future} that is {@link Runnable}. Successful execution of + * the <tt>run</tt> method causes completion of the <tt>Future</tt> + * and allows access to its results. + * @see FutureTask + * @see Executor + * @since 1.6 + * @author Doug Lea + * @param <V> The result type returned by this Future's <tt>get</tt> method + */ +public interface RunnableFuture<V> extends Runnable, Future<V> { + /** + * Sets this Future to the result of its computation + * unless it has been cancelled. + */ + void run(); +} + + + ==> diff -u -I '%[A-Z]%' -I '@(#)' -I '^[ */]*$' -I @version -I @test -w /dev/null /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/RunnableScheduledFuture.java --- /dev/null 2005-06-11 15:51:45.000000000 -0700 +++ /u/martin/src/jsr166/cvs/src/main/java/util/concurrent/RunnableScheduledFuture.java 2005-05-23 19:59:26.652994000 -0700 @@ -0,0 +1,28 @@ +/* +package java.util.concurrent; + +/** + * A {@link ScheduledFuture} that is {@link Runnable}. Successful + * execution of the <tt>run</tt> method causes completion of the + * <tt>Future</tt> and allows access to its results. + * @see FutureTask + * @see Executor + * @since 1.6 + * @author Doug Lea + * @param <V> The result type returned by this Future's <tt>get</tt> method + */ +public interface RunnableScheduledFuture<V> extends RunnableFuture<V>, ScheduledFuture<V> { + + /** + * Returns true if this is a periodic task. A periodic task may + * re-run according to some schedule. A non-periodic task can be + * run only once. + * @return true if this task is periodic. + */ + boolean isPeriodic(); +} ###@###.### 2005-06-11 23:29:13 GMT
11-06-2005

EVALUATION Will be integrated into mustang as part of jsr166x project. ###@###.### 2005-05-28 00:21:40 GMT
28-05-2005