Changing the javadoc to not advertise RequestProcessor.getDefault() at all as it is almost all the time misused.
authorJaroslav Tulach <jtulach@netbeans.org>
Sun, 22 Nov 2009 11:34:19 +0100
changeset 8537185f5c8d0b3
parent 852 b1cecb0b4f89
child 855 56b647865e0f
child 951 3a8d1b142353
Changing the javadoc to not advertise RequestProcessor.getDefault() at all as it is almost all the time misused.
openide.util/src/org/openide/util/RequestProcessor.java
     1.1 --- a/openide.util/src/org/openide/util/RequestProcessor.java	Wed Nov 18 12:27:13 2009 -0500
     1.2 +++ b/openide.util/src/org/openide/util/RequestProcessor.java	Sun Nov 22 11:34:19 2009 +0100
     1.3 @@ -53,73 +53,111 @@
     1.4  import java.util.logging.Level;
     1.5  import java.util.logging.Logger;
     1.6  
     1.7 -/** Request processor that is capable to execute requests in dedicated threads.
     1.8 - * You can create your own instance or use the shared one.
     1.9 +/** Request processor is {@link Executor} (since version 7.16) capable to
    1.10 + * perform asynchronous requests in a dedicated thread pool.
    1.11 + * <A name="use_cases">There are several use cases for RequestProcessor</A>,
    1.12 + * most of them start with creating own <code>RequestProcessor</code>
    1.13 + * instance (which by itself is quite lightweight).
    1.14   *
    1.15 - * <P><A name="use_cases">There are several use cases for RequestProcessor:</A>
    1.16 + * <h5>Do something later</h5>
    1.17   *
    1.18 - * <UL><LI>Having something done asynchronously in some other thread,
    1.19 - *  not insisting on any kind of serialization of the requests:
    1.20 - *  Use <CODE>RequestProcessor.{@link RequestProcessor#getDefault
    1.21 - *  }.{@link #post(java.lang.Runnable) post(runnable)}</CODE>
    1.22 - *  for this purpose.
    1.23 - * <LI>Having something done later in some other thread:
    1.24 - *  Use <CODE>RequestProcessor.{@link RequestProcessor#getDefault
    1.25 - *  }.{@link #post(java.lang.Runnable,int) post(runnable,&nbsp;delay)}</CODE>
    1.26 - * <LI>Having something done periodically in any thread: Use the
    1.27 - *  {@link RequestProcessor.Task}'s ability to
    1.28 - *  {@link RequestProcessor.Task#schedule schedule()}, like
    1.29 - *  <PRE>
    1.30 - *      static RequestProcessor.Task CLEANER = RequestProcessor.getDefault().post(runnable,DELAY);
    1.31 - *      public void run() {
    1.32 - *          doTheWork();
    1.33 - *          CLEANER.schedule(DELAY);
    1.34 - *      }
    1.35 - *  </PRE>
    1.36 - *  <STRONG>Note:</STRONG> Please think twice before implementing some periodic
    1.37 - *  background activity. It is generally considered evil if it will run
    1.38 -    regardless of user actions and the application state, even while the application
    1.39 -    is minimized / not currently used.
    1.40 - * <LI>Having something done in some other thread but properly ordered:
    1.41 - *  Create a private instance of the
    1.42 - *  {@link RequestProcessor#RequestProcessor(java.lang.String) RequestProcessor(name)}</CODE>
    1.43 - *  and use it from all places you'd like to have serialized. It works
    1.44 - *  like a simple Mutex.
    1.45 - * <LI>Having some entity that will do processing in a limited
    1.46 - *  number of threads paralelly: Create a private instance of the
    1.47 - *  {@link RequestProcessor#RequestProcessor(java.lang.String,int) RequestProcessor(name,throughput)}</CODE>
    1.48 - *  set proper throughput and use it to schedule the work.
    1.49 - *  It works like a queue of requests passing through a semafore with predefined
    1.50 - *  number of <CODE>DOWN()</CODE>s.
    1.51 - * </UL>
    1.52 + * In case you want something to be done later in some background thread,
    1.53 + * create an instance of <code>RequestProcessor</code> and post tasks to it.
    1.54 + * <pre>
    1.55 + * private static final RequestProcessor RP = new RequestProcessor("My tasks");
    1.56 + * // later
    1.57 + * RP.{@link #post(java.lang.Runnable,int) post(runnable,&nbsp;delay)}
    1.58 + * </pre>
    1.59   *
    1.60 - * <STRONG>Note:</STRONG> If you don't need to serialize your requests but
    1.61 - * you're generating them in bursts, you should use your private
    1.62 - * <CODE>RequestProcessor</CODE> instance with limited throughput (probably
    1.63 - * set to 1), NetBeans would try to run all your requests in parallel otherwise.
    1.64 + * The above example guarantees that there is at most one runnable being
    1.65 + * processed in parallel. All your requests are serialized and processed
    1.66 + * one by one. <code>RP</code> works here like a simple mutex.
    1.67 + * <p>
    1.68 + * In case you want more tasks to run in parallel (not very often use case)
    1.69 + * you can specify higher
    1.70 + * throughput via {@link #RequestProcessor(java.lang.String, int)}. Then
    1.71 + * the <code>RP</code> works like a queue of requests passing through a
    1.72 + * semafore with predefined number of <CODE>DOWN()</CODE>s.
    1.73 + * <p>
    1.74 + * You can wait for your tasks to be processed by keeping a reference to the
    1.75 + * last one and using {@link RequestProcessor.Task#waitFinished waitFinished()}:
    1.76 + * <pre>
    1.77 + * private static final RequestProcessor RP = new RequestProcessor("My tasks");
    1.78 + * private volatile {@link RequestProcessor.Task} last;
    1.79   *
    1.80 - * <P>
    1.81 + * // when posting update the task
    1.82 + * last = RP.{@link #post(java.lang.Runnable,int) post(runnable,&nbsp;delay)}
    1.83 + *
    1.84 + * // later wait
    1.85 + * last.{@link RequestProcessor.Task#waitFinished waitFinished()}
    1.86 + * </pre>
    1.87 + *
    1.88 + * <h5>Periodic task</h5>
    1.89 + *
    1.90 + * It is also possible to do something periodically. Use the {@link RequestProcessor.Task#schedule schedule} method:
    1.91 + * <pre>
    1.92 + * class Periodic implements Runnable {
    1.93 + *   private static final RequestProcessor RP = new RequestProcessor("My tasks");
    1.94 + *   private final RequestProcessor.Task CLEANER = RP.{@link #create(java.lang.Runnable) create(this)};
    1.95 + *   public void run() {
    1.96 + *     doTheWork();
    1.97 + *     CLEANER.schedule(DELAY);
    1.98 + *   }
    1.99 + * }
   1.100 + * </pre>
   1.101 + *  Please think twice before using such periodic
   1.102 + *  background activity. It is generally considered evil if some code runs
   1.103 + *  without any user action. Your code shall respect  the application's state,
   1.104 + *  and for example when the application is minimized, do nothing.
   1.105 + *
   1.106 + * <h5>Sliding task</h5>
   1.107 + *
   1.108 + * Often you want to perform an update of your object internals
   1.109 + * based on changes in some model. However your update may be costly
   1.110 + * and you want to do it just once, regardless of how many changes are
   1.111 + * reported by the model. This can be achieved with a sliding task:
   1.112 + * <pre>
   1.113 + * class Updater implements PropertyChangeListener, Runnable {
   1.114 + *   private static final RequestProcessor RP = new RequestProcessor("My tasks");
   1.115 + *   private final RequestProcessor.Task UPDATE = RP.{@link #create(java.lang.Runnable) create(this)};
   1.116 + *
   1.117 + *   public void propertyChange(PropertyChangeEvent ev) {
   1.118 + *     UPDATE.{@link RequestProcessor.Task#schedule schedule(1000)};
   1.119 + *   }
   1.120 + *
   1.121 + *   public void run() {
   1.122 + *     doTheWork();
   1.123 + *   }
   1.124 + * }
   1.125 + * </pre>
   1.126 + * The above code coaleases all events that arrive in 1s and for all of them
   1.127 + * does <code>doTheWork</code> just once.
   1.128 + *
   1.129 + *
   1.130 + * <h5>Interruption of tasks</h5>
   1.131 + *
   1.132   * Since version 6.3 there is a conditional support for interruption of long running tasks.
   1.133 - * There always was a way how to cancel not yet running task using {@link RequestProcessor.Task#cancel }
   1.134 - * but if the task was already running, one was out of luck. Since version 6.3
   1.135 + * There always was a way to cancel not yet running task using {@link RequestProcessor.Task#cancel }
   1.136 + * but if the task's run() method was already running, one was out of luck.
   1.137 + * Since version 6.3
   1.138   * the thread running the task is interrupted and the Runnable can check for that
   1.139   * and terminate its execution sooner. In the runnable one shall check for 
   1.140   * thread interruption (done from {@link RequestProcessor.Task#cancel }) and 
   1.141   * if true, return immediatelly as in this example:
   1.142 - * <PRE>
   1.143 + * <pre>
   1.144 + * private static final RequestProcessor RP = new {@link #RequestProcessor(String,int,boolean) RequestProcessor("Interruptible", 1, true)};
   1.145   * public void run () {
   1.146 - *     while (veryLongTimeLook) {
   1.147 + *     while (veryLongTimeLoop) {
   1.148   *       doAPieceOfIt ();
   1.149   *
   1.150   *       if (Thread.interrupted ()) return;
   1.151   *     }
   1.152   * }
   1.153 - * </PRE>
   1.154 - * Since version 7.16 it implements {@link Executor}
   1.155 + * </pre>
   1.156   * 
   1.157   * @author Petr Nejedly, Jaroslav Tulach
   1.158   */
   1.159 -public final class RequestProcessor implements Executor{
   1.160 +public final class RequestProcessor implements Executor {
   1.161      /** the static instance for users that do not want to have own processor */
   1.162      private static RequestProcessor DEFAULT = new RequestProcessor();
   1.163