View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.util.thread;
20  
21  import java.lang.reflect.Constructor;
22  import java.util.concurrent.Executor;
23  
24  import org.eclipse.jetty.util.Loader;
25  import org.eclipse.jetty.util.log.Log;
26  import org.eclipse.jetty.util.log.Logger;
27  import org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume;
28  
29  /**
30   * <p>An {@link ExecutionStrategy} executes {@link Runnable} tasks produced by a {@link Producer}.
31   * The strategy to execute the task may vary depending on the implementation; the task may be
32   * run in the calling thread, or in a new thread, etc.</p>
33   * <p>The strategy delegates the production of tasks to a {@link Producer}, and continues to
34   * execute tasks until the producer continues to produce them.</p>
35   */
36  public interface ExecutionStrategy
37  {
38      /**
39       * <p>Initiates (or resumes) the task production and execution.</p>
40       * <p>This method guarantees that the task is never run by the
41       * thread that called this method.</p>
42       *
43       * @see #execute()
44       */
45      public void dispatch();
46  
47      /**
48       * <p>Initiates (or resumes) the task production and execution.</p>
49       * <p>The produced task may be run by the same thread that called
50       * this method.</p>
51       *
52       * @see #dispatch()
53       */
54      public void execute();
55  
56      /**
57       * <p>A producer of {@link Runnable} tasks to run.</p>
58       * <p>The {@link ExecutionStrategy} will repeatedly invoke {@link #produce()} until
59       * the producer returns null, indicating that it has nothing more to produce.</p>
60       * <p>When no more tasks can be produced, implementations should arrange for the
61       * {@link ExecutionStrategy} to be invoked again in case an external event resumes
62       * the tasks production.</p>
63       */
64      public interface Producer
65      {
66          /**
67           * <p>Produces a task to be executed.</p>
68           *
69           * @return a task to executed or null if there are no more tasks to execute
70           */
71          Runnable produce();
72      }
73  
74      public static class Factory
75      {
76          private static final Logger LOG = Log.getLogger(Factory.class);
77  
78          public static ExecutionStrategy instanceFor(Producer producer, Executor executor)
79          {
80              // TODO remove this mechanism before release
81              String strategy = System.getProperty(producer.getClass().getName()+".ExecutionStrategy");
82              if (strategy!=null)
83              {
84                  try
85                  {
86                      Class<? extends ExecutionStrategy> c = Loader.loadClass(producer.getClass(),strategy);
87                      Constructor<? extends ExecutionStrategy> m = c.getConstructor(Producer.class,Executor.class);
88                      LOG.info("Use {} for {}",c.getSimpleName(),producer.getClass().getName());
89                      return  m.newInstance(producer,executor);
90                  }
91                  catch(Exception e)
92                  {
93                      LOG.warn(e);
94                  }
95              }
96              
97              return new ExecuteProduceConsume(producer,executor);
98          }
99      }
100 }