2016-10-06 11 views
2

Ich muss eine geplante Aufgabe pausieren und fortsetzen.Geplante Aufgabe pausieren und fortsetzen

Ich sehe viele Codebeispiele, um eine Aufgabe abzubrechen(), aber ich müsste sie dann auch fortsetzen/neu starten. Ich sehe Vorschläge dabei:

public void init(){ 
    scheduledTaskExecutor.getScheduledThreadPoolExecutor().setRemoveOnCancelPolicy(true); 
} 
public void schedule(String id, Runnable task){ 
    ScheduledFuture<?> scheduledFuture = scheduledTaskExecutor.scheduleAtFixedRate(task); 
    runningTaskRegistry.put(id, task); 
} 

public void suspend(String id){ 
    ScheduledFuture<?> scheduledFuture = runningTaskRegistry.get(serviceName); 
    if(scheduledFuture != null){ 
     scheduledFuture.cancel(false); 
     try{ 
      scheduledFuture.get(); 
     } catch (InterruptedException | ExecutionException | CancellationException e){ 
      // I do not want the currently running task finishing after this point 
     } 
    } 
} 

... und dann muss ich erneut planen statt neu zu starten.

Ist das wirklich der beste Weg, dies zu tun?

+0

Im Allgemeinen ist eine Neuplanung Ihrer Aufgabe der beste Weg, dies zu tun. Ein Hack, der einem einfällt, benutzt einen [single-thread executor] (http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadScheduledExecutor--), und übergibt es eine Aufgabe, die wartet, bis die Pause-Bedingung falsch ist. – VGR

+0

Singlethread-Executor ist hier keine Option: Ich habe dutzende von lang laufenden Prozessen zu laufen und einige von ihnen ist ziemlich langwierig. – BTakacs

Antwort

0

Ich würde lieber Neuterminierung über Pause und Fortsetzen. Nicht nur, weil ich nicht weiß, wie das geht, sondern auch, weil pausierte Aufgaben ihre Threads wahrscheinlich nicht freigeben werden. Während dieser Zeit blockieren diese Executor-Threads und tun nichts, auch wenn in der Task-Warteschlange andere Tasks warten.

Um Zwischenergebnisse nicht zu verlieren, können Sie sie in eine andere Warteschlange stellen, die abgeholt wird, bevor neue Aufgaben geplant werden. Sie können basierend auf dieser Warteschlange auch das Anhalten und Fortsetzen implementieren.

+0

Ich stimme völlig zu, dass das Blockieren eines Executor-Threads keine gute Lösung ist. Ich dachte nur, dass der Executor selbst das Entfernen in eine temporäre Liste machen kann und dann die Neuterminierung ... :-) Eine weitere Lösung könnte sein, einen Wrapper/Proxy um Runnable zu erstellen und dort Pause zu machen und weiterzumachen: nicht durch Blockieren des Threads aber durch das Ignorieren der ursprünglichen runnable wenn pausiert :-) Das würde nur minimalen Overhead mit minimalen Boilerplate-Code verursachen. – BTakacs

+0

@BTakacs Ich denke, es hängt wirklich davon ab, was Ihre Aufgaben zu tun haben und ob Sie Zwischenergebnisse wiederverwenden können. Wie bereits erwähnt, kenne ich keine Implementierung, die * effiziente * pausierbare und fortsetzbare Aufgaben ermöglicht, d. H. Threads werden nicht nur blockiert. Ich würde vorschlagen, dass Sie ['BlockingQueue'] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html) ausprobieren, um Aufgaben zu" parken "und abzuholen nochmal. Lassen Sie es mich wissen, wenn Sie möchten, dass ich Ihnen ein Beispiel gebe. – beatngu13

Verwandte Themen