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 }