2009-06-10 10 views
0

Ich führe mehrere idempotente Aufgaben aus, um einen Datenstapel zu sammeln. Ich habe herausgefunden, dass sich die Berechnung oft aufgrund von ein paar Aufgaben von hundert signifikant verzögert.Beschleunigung von idempotenten Aufgaben, die verstreut sind

Was ich möchte ist eine Möglichkeit, diese Aufgaben zu beobachten und die Nachzügler erneut zu starten, wenn sie sich erheblich verspäten.

Gibt es eine Standardbibliothek oder ein Idiom dafür in Java? Ich verwende derzeit das ExecutorService/ExecutorCompletionService Paar, um die Arbeit zu erledigen.

Antwort

2

Wenn Sie Zugriff auf das Objekt Future haben, das diese Aufgabe darstellt, können Sie bei Bedarf isDone() und cancel() überprüfen. Sie müssten diese zukünftigen Objekte abfragen und erneut einreichen. Es hängt auch von Ihrem zugrunde liegenden Runnables InterruptExceptions entsprechend behandeln.

1

Sie könnten einen Task-Manager-Typ erstellen, der einen Verweis auf jede der Aufgaben enthält. Dieser Task-Manager kann für das Starten jeder Task und das Verwalten des ExecutorService verantwortlich sein. Die erste und letzte Operation jeder Aufgabe besteht darin, den Manager den Beginn und das Ende der Aufgabe zu registrieren. Der Manager kann dann ein statistisches Bild erstellen, das den Durchschnitt der Zeit darstellt, die zur Ausführung der einzelnen Aufgaben benötigt wird.

Der Task-Manager durchsucht regelmäßig die Liste der ausgeführten Aufgaben auf der Suche nach "Ausreißern", die noch immer ausgeführt werden und erheblich von der durchschnittlichen Zeit für eine bestimmte Aufgabe abweichen. Er kann diese Aufgaben dann abbrechen und neu starten.

Hier ist eine sehr grobe Skizze von dem, was man tun könnte ...

public class Task implements Runnable { 
    protected TaskManager manager_ = null; 
    protected String taskClass_ = null; 
    protected String taskId_ = null; 

    protected Task(TaskManager manager, String taskClass) { 
     manager_ = manager; 
     taskClass_ = taskClass; 
    } 

    /* 
     * Override this and perform specific task. 
     */ 
    protected void perform() { } 

    public void run() { 
     try { 
      manager_.taskStarted(this); 
      perform(); 
      manager_.taskCompleted(this); 
     catch(InterruptedException) { 
      manager_.taskAborted(this); 
     } 
     finally { 
     } 
    } 
} 


public class TaskManager { 
    ExecutorService service_ = null; 

    public TaskManager() { 
     service_ = new ExecutorService(); 
     // start the monitoring thread. 
     service_.execute(this); 
    } 

    public void runTask(Task t) { 
     service_.execute(t); 
    } 

    public void taskStarted(Task t) { 

     1. Note the time that this task (with unique id) has started. 
     2. Add time to a hash map. 
     3. Add task to list of executing tasks. 
    } 

    public void taskComplete(Task t) { 
     1. Find the task id in hash map 
     2. note how long it took to execute. 
     3. modify statistics of how long the task took against 
      the task Class Id. 
     4. Remove task from list of executing tasks. 
    } 

    public void taskAborted(Task t) { 
     // just remove the task from list of running tasks 
     // without altering the statistics. 
    } 
    public void run() { 
     1. Go though the list of executing tasks looking for 
      tasks whose current time - start time is outside the 
      time statistics for the task class id. 
     2. cancel the task and start again. 
    } 
} 
Verwandte Themen