Estoy de acuerdo en la respuesta de Dave, pero si necesita cortar el tiempo de CPU en todos los "grupos", es decir, todos los grupos de tareas deben progresar en paralelo, es posible que encontrar este tipo de construcción útil (. mediante la eliminación de "bloquear" esto funcionó bien en mi caso aunque imagino que tiende a utilizar más memoria):
class TaskAllocator {
private final ConcurrentLinkedQueue<Queue<Runnable>> entireWork
= childQueuePerTaskGroup();
public Queue<Runnable> lockTaskGroup(){
return entireWork.poll();
}
public void release(Queue<Runnable> taskGroup){
entireWork.offer(taskGroup);
}
}
y
class DoWork implmements Runnable {
private final TaskAllocator allocator;
public DoWork(TaskAllocator allocator){
this.allocator = allocator;
}
pubic void run(){
for(;;){
Queue<Runnable> taskGroup = allocator.lockTaskGroup();
if(task==null){
//No more work
return;
}
Runnable work = taskGroup.poll();
if(work == null){
//This group is done
continue;
}
//Do work, but never forget to release the group to
// the allocator.
try {
work.run();
} finally {
allocator.release(taskGroup);
}
}//for
}
}
a continuación, puede utilizar número óptimo de hilos para ejecutar DoWork
tarea. Es una especie de un equilibrio de carga por turnos ..
Incluso se puede hacer algo más sofisticado, utilizando esta vez de un simple cola en TaskAllocator
(grupos de trabajo, con más tarea pendiente tienden a quedar ejecutada)
ConcurrentSkipListSet<MyQueue<Runnable>> sophisticatedQueue =
new ConcurrentSkipListSet(new SophisticatedComparator());
donde SophisticatedComparator
es
class SophisticatedComparator implements Comparator<MyQueue<Runnable>> {
public int compare(MyQueue<Runnable> o1, MyQueue<Runnable> o2){
int diff = o2.size() - o1.size();
if(diff==0){
//This is crucial. You must assign unique ids to your
//Subqueue and break the equality if they happen to have same size.
//Otherwise your queues will disappear...
return o1.id - o2.id;
}
return diff;
}
}
"Sin embargo, los hilos podría bloquear entre sí y el rendimiento no está maximizada.". ¿Quiere decir que las tareas individuales acceden a una estructura o recurso de datos compartidos y esta es la causa de la disputa? – Adamski
¿Conoces todas las tareas de un grupo por adelantado? Esto es importante al elegir una solución (colas versus sin colas) –