java - 使用 ScheduledExecutorService 时在哪里对计划任务执行最终清理

标签 java sockets concurrency executors

任务是实现一个非常非常简化的计算“云”。云实例(“引擎”)应该定期向主管发送保持 Activity 消息(“命令”)。我已经使用以下任务实现了这一点:

public class KeepAlive implements Runnable {
    Engine engine;
    DatagramSocket sock;

    public KeepAlive(Engine engine) {
        this.engine = engine;
        sock = new DatagramSocket();
    }

    public void run() {
        DatagramSocket sock = null;

        EngineArguments args = engine.getArgs();

        KeepAliveCommand cmd = new KeepAliveCommand(…);
        byte[] data = cmd.toString().getBytes("UTF-8");
        DatagramPacket p = new DatagramPacket(data, data.length, InetAddress.getByName(args.getSchedulerHost()), args.getSchedulerPort());
        sock.send(p);
    }    
}

计划使用 scheduleAtFixedRate() 执行。我正在使用 shutdownNow() 进行优雅(ish)关闭以避免必须保留对长时间运行的任务的显式引用。

是否有任何“干净”的方法来执行特定于任务的清理(关闭DatagramSocket)?或者,在计划运行之间保留 DatagramSocket 实例是否有意义,或者我可以每次都创建一个新实例吗?

最佳答案

据我所知,您有两个选择:

  1. 跟踪“套接字池”中的套接字并使用该池的“发送”方法。 然后,在关闭执行器后,关闭池
  2. 扩展ScheduledThreadPoolExecutor,这可能有点困难。但是,API 很干净...请注意,您可以“装饰”任务,还有一个“终止”方法。

我喜欢“套接字池”的想法。然后,如何处理连接取决于池(即,如果您有持久连接或每个请求创建一个连接)

关于java - 使用 ScheduledExecutorService 时在哪里对计划任务执行最终清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7985912/

相关文章:

java - 如何在单次遍历中从一个顶点创建多条边

sockets - WSAStartup 和 WSACleanup 的成本是多少?

java - CyclicBarrier:导致屏障跳闸的 'x' 个线程中的 'y' 完成执行并终止

go - golang 编译器何时可以重新排序命令以及同步原语如何影响它?

java - 如何使用 Hibernate 为 Spring 数据 JPA 的所有查找方法添加全局 where 子句?

java - 我在 IntelliJ 上收到一条错误消息,提示无法创建带有奇怪错误消息的类

java - 如何启用 Swagger UI? Tomcat、SpringMVC、REST

java - 如果服务器超时,Socket InputStream read() 是否解除阻塞?

javascript - nodejs 错误 : Parse Error at Socket. ondata

java - 当其他任务完成时,强制 BufferedWriter 从 BlockingQueue 写入