United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6277663 : Improve extensibility of thread pools

Details
Type:
Enhancement
Submit Date:
2005-05-28
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2005-09-04
Component:
core-libs
OS:
generic
Sub-Component:
java.util.concurrent
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports

Sub Tasks

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
EVALUATION

Will be integrated into mustang as part of jsr166x project.
###@###.### 2005-05-28 00:21:40 GMT
                                     
2005-05-28
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
                                     
2005-06-11



Hardware and Software, Engineered to Work Together