0

我正在使用 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??
}

}

知道如何解决吗?

谢谢!

纽斯

4

2 回答 2

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;
        }
    }
}
于 2014-03-03T14:39:37.583 回答
0

这是海湾方式。你不应该试图从 Executor 中获取结果,因为它只负责调度和执行任务,而不是它们内部发生的事情。

您的TareaActualizacion可运行文件应该将结果发布到您需要的另一段代码中。这可以使用队列或在最简单的情况下实现SwingUtilities.invokeLater()

于 2014-03-03T11:25:13.970 回答