Где выполнить окончательную очистку для запланированной задачи при использовании ScheduledExecutorService - PullRequest
1 голос
/ 02 ноября 2011

Задача - реализовать очень и очень упрощенное вычислительное «облако». Облачные экземпляры («движки») должны регулярно отправлять сообщения поддержки («команды») супервизору. Я реализовал это, используя следующую задачу:

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 () . Я делаю изящное (ish) завершение использования shutdownNow () , чтобы избежать необходимости сохранять явные ссылки на долгосрочные задачи.

Есть ли какой-либо "чистый" способ выполнить очистку, специфичную для задачи (закрытие DatagramSocket)? С другой стороны, имеет ли смысл хранить экземпляр DatagramSocket между запланированными запусками или я могу просто каждый раз создавать новый?

1 Ответ

1 голос
/ 05 декабря 2011

На мой взгляд, у вас есть 2 варианта:

  1. Отслеживайте сокеты внутри «пула сокетов» и используя метод «send» этого пула. Затем, после выключения исполнителя, вы закрываете пул
  2. Расширить ScheduledThreadPoolExecutor, что может быть немного сложнее. Но API чист ... Обратите внимание, что вы можете "украшать" задачи, также есть метод "termintated".

Мне нравится идея "пула сокетов". Затем способ обработки соединения зависит от пула (т. Е. Если у вас есть постоянное соединение или вы создаете его для каждого запроса)

...