2012-10-04 22 views
14

He buscado mucho pero no he podido encontrar ninguna solución. utilizo agrupación de hebras de Java de tal manera:Especifique la ejecución de orden de tareas en Java

ExecutorService c = Executors.newFixedThreadPool(3); 
for (int i = 0; i < 10; ++i) { 
    c.execute(new MyTask(i)); 
} 

de tal modo las tareas se ejecutan en el consiguiente fin (como en la cola). Pero necesito cambiar la estrategia de "seleccionar la siguiente tarea". Por lo tanto, quiero asignar a cada tarea la prioridad especificada (no es prioridad de subprocesos) y las tareas de ejecución corresponden a estas prioridades. Entonces, cuando el ejecutor ha terminado otra tarea, elige la siguiente tarea como tarea con máxima prioridad. Describe el problema común. Tal vez haya un enfoque más simple que no tenga en cuenta las prioridades. Selecciona la última tarea añadida como siguiente para ejecutar en lugar de la primera agregada. En general, FixedThreadPool usa la estrategia FIFO. ¿Puedo usar, por ejemplo, la estrategia LIFO?

Respuesta

11

Se puede utilizar para especificar PriorityBlockingQueue cola para ThreadPoolExecutor.

public class PriorityExecutor extends ThreadPoolExecutor { 

    public PriorityExecutor(int corePoolSize, int maximumPoolSize, 
      long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { 
     super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); 
    } 
    //Utitlity method to create thread pool easily 
    public static ExecutorService newFixedThreadPool(int nThreads) { 
     return new PriorityExecutor(nThreads, nThreads, 0L, 
       TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>()); 
    } 
    //Submit with New comparable task 
    public Future<?> submit(Runnable task, int priority) { 
     return super.submit(new ComparableFutureTask(task, null, priority)); 
    } 
    //execute with New comparable task 
    public void execute(Runnable command, int priority) { 
     super.execute(new ComparableFutureTask(command, null, priority)); 
    } 
} 

Definir ComparableFutureTask comparar en prioridad.

class ComparableFutureTask<T> extends FutureTask<T> 
     implements 
      Comparable<ComparableFutureTask<T>> { 

    volatile int priority = 0; 

    public ComparableFutureTask(Runnable runnable, T result, int priority) { 
     super(runnable, result); 
     this.priority = priority; 
    } 
    public ComparableFutureTask(Callable<T> callable, int priority) { 
     super(callable); 
     this.priority = priority; 
    } 
    @Override 
    public int compareTo(ComparableFutureTask<T> o) { 
     return Integer.valueOf(priority).compareTo(o.priority); 
    } 
    } 
+0

+1 tal vez dar un fragmento para que esto sea mejor. – Tudor

+5

Esto no puede funcionar porque 'newTaskFor' envolverá ComparableFutureTask en FutureTask, que no es comparable. También debe anular los dos métodos 'newTaskFor'. – assylias

+1

Ver [esta publicación] (http://stackoverflow.com/a/16834473/829571) para obtener un ejemplo simplista. – assylias

7

ThreadPoolExecutor constructor acepta BlockingQueue. Puede pasar la cola como PriorityBlockingQueue. No hace que ningún concesionario ordene la necesidad de pasar comparadores personalizados para mantener el orden.

static BlockingQueue<Task> queue=new PriorityBlockingQueue<Task>(MAXPOOL,new TaskComparator()); 

static ThreadPoolExecutor threadpool = new ThreadPoolExecutor(30, MAXPOOL, 
     MAXPOOL, TimeUnit.SECONDS, (PriorityBlockingQueue) queue, new mThreadFactory()); 



class TaskComparator implements Comparator<Task>{ 
    public int compare(Task t1, Task t2){ 
    //write you own logic to compare two task. 
    } 
} 
+1

Buena publicación, excepto que 'igual' devuelve' boolean' y 'compare' devuelve' int' . Creo que quisiste usar 'compareTo'. – Tudor

+0

+1 gracias por el aviso. –

Cuestiones relacionadas