2014-03-03 21 views
0

我正在使用ScheduledThreadPoolExecutor,並且我不知道該如何處理某些事情。如何從ScheduledThreadPoolExecutor的afterExecute中獲取任務的數據

我安排一些任務是這樣的:

scheduledExecService = new ExtendedScheduledExecutor(numThreads, myThreadFactory); 
TareaActualizacion act = new TareaActualizacion(inst); 
ScheduledFuture<?> handle = scheduledExecService.scheduleWithFixedDelay(act, retrasoInicial, segundosRefresco, TimeUnit.SECONDS); 

行爲是由參數recive一些數據可運行的類:在我想要的ExtendedSecheduledExecutor的afterExecute方法

public class TareaActualizacion implements Runnable { 
private Instalacion instalacion; 
public TareaActualizacion(Instalacion instalacion) { 
    this.instalacion = instalacion; 
} 
@Override 
public void run() { 
    //Do something 
} 
public Instalacion getInstalacion() { 
    return instalacion; 
} 
} 

現在獲得任務TareaActualizacion的對象Instalacion,但我不知道該怎麼做。 我ExtendedScheduledExecutor類看起來是這樣的:

public class ExtendedScheduledExecutor extends ScheduledThreadPoolExecutor{ 

public ExtendedScheduledExecutor(int arg0) { 
    super(arg0); 
} 
public ExtendedScheduledExecutor(int arg0, ThreadFactory arg1) { 
    super(arg0, arg1); 
} 

@Override 
protected void afterExecute(Runnable r, Throwable t) 
{ 
    super.afterExecute(r, t); 

    System.out.println("Executing afterExecute. Throwable is " + t); 
    if (t != null) 
     t.printStackTrace(); 
    //I need to get the Instalacion attribute from TareaActualizacion task. How can I do it?? 
} 

}

的我怎麼能解決這個問題的任何想法?

謝謝!

諾伊斯

回答

0

這是一個海灣的方式。您不應該試圖從Executor中獲得結果,因爲它只負責調度和執行任務,而不是負責執行任務。

您的TareaActualizacion runnable應該將結果發佈到另一段代碼,您需要它。這可以使用隊列或在最簡單的情況下實現SwingUtilities.invokeLater()

+0

我想我必須解釋爲什麼我這樣做。每個任務都會更新一些與Instalacion相關的數據庫數據。 因此,更新數據後,我需要更新顯示此數據的屏幕上的圖表,但前提是用戶正在查閱已更新的Instalacion的數據。這就是爲什麼我需要知道與哪個Instalacion是相關的任務,因爲我需要知道如果我必須刷新屏幕上的圖表。我的想法是我在帖子中解釋的,但也許有更好的解決方案 – user3374578

1

正如Stephan在https://stackoverflow.com/a/22145530中已經指出的那樣,您應該嘗試從通知中分離調度和執行。

對此的一種方法可能是將實際任務(TareaActualizacion)包裝到Runnable接口的另一個實現中,該接口只執行實際任務,然後通知有關已執行任務的回調。

根據您精確的要求,可能有幾個自由度的實施,但一般的方法可以大致是這樣的:

import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

public class ScheduledTaskNotification 
{ 
    public static void main(String[] args) throws Exception 
    { 
     ScheduledExecutorService executor = Executors.newScheduledThreadPool(4); 

     int n = 3; 
     for (int i = 0; i < n; i++) 
     { 
      UpdateTask updateTask = new UpdateTask(i); 

      RunnableCallback<UpdateTask> callback = new RunnableCallback<UpdateTask>() 
      { 
       @Override 
       public void runnableFinished(UpdateTask updateTask) 
       { 
        System.out.println("Finished "+updateTask+", id "+updateTask.getID()); 
       } 
      }; 

      Runnable runnableWithCallback = 
       createRunnableWithCallback(updateTask, callback); 

      executor.scheduleWithFixedDelay(
       runnableWithCallback, 1000, 200+i*200, 
       TimeUnit.MILLISECONDS); 
     } 
    } 

    static interface RunnableCallback<T extends Runnable> 
    { 
     void runnableFinished(T runnable); 
    } 

    private static <T extends Runnable> Runnable createRunnableWithCallback(
     final T runnable, final RunnableCallback<T> callback) 
    { 
     return new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       runnable.run(); 
       callback.runnableFinished(runnable); 
      } 
     }; 
    } 

    private static class UpdateTask implements Runnable 
    { 
     private final int id; 

     UpdateTask(int id) 
     { 
      this.id = id; 
     } 

     @Override 
     public void run() 
     { 
      System.out.println("Run "+this); 
     } 

     int getID() 
     { 
      return id; 
     } 

     @Override 
     public String toString() 
     { 
      return "UpdateTask "+id; 
     } 
    } 
} 
相關問題