我正在使用ScheduledThreadPoolExecutor而且我不太热衷于处理某些事情。
我正在以这种方式安排一些任务:
scheduledExecService = new ExtendedScheduledExecutor(numThreads, myThreadFactory);
TareaActualizacion act = new TareaActualizacion(inst);
ScheduledFuture<?> handle = scheduledExecService.scheduleWithFixedDelay(act, retrasoInicial, segundosRefresco, TimeUnit.SECONDS);
act是一个Runnable类,它通过参数:
返回一些数据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;
}
}
现在在ExtendedSecheduledExecutor的afterExecute方法中,我想获取任务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 :(得分: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;
}
}
}
答案 1 :(得分:0)
这是一种海湾方式。你不应该试图从Executor中获取结果,因为它只负责调度和执行任务,而不是发生在它们内部的任何事情。
您的TareaActualizacion
runnable应该将结果发布到您需要的另一段代码中。这可以使用队列或最简单的SwingUtilities.invokeLater()
来实现。