Сохраните и перезапустите пул потоков после выключения сервера

Мое приложение имеет несколько потоков. В случае, если сервер выйдет из строя или перезапустится, я хочу выполнить ТОЛЬКО те потоки, которые не были выполнены. Например, в приведенном ниже фрагменте: подумайте, отключается ли сервер после выполнения потоков с номерами 1,4,2. Приложение должно выполнять 2, 3 и 5 потоков после перезапуска сервера.

Задача потоков АТОМИЧЕСКАЯ по своей природе. Либо все делается, либо ничего не происходит. Поэтому мне нужно как-то сохранить состояние каждого уже выполненного потока. Как я могу это сделать?

class HugeJob implements Runnable {
int param;
 public HugeJob(int var) {
       this.param = var;
   }

   public void run() {
       //This is an ATOMIC task i.e. either all gets done or nothing
       //Each thread task takes ~20 minute. Heavy I/O and network operations
       //I have to make sure no thread executes more than once even if server is restarted
       System.out.println(this.param);
   }
}

public class ThreadSample {

public static void main(String [] args)
{
    for(int i =0; i<5;i++)
      {
        HugeJob obj = new HugeJob(i);
        new Thread(obj).start();
      }
    }
}

Спасибо за помощь.

Изменить Могу ли я использовать Quartz для достижения этой цели? Стоит ли создавать каждый поток как отдельное задание и сохранять его с помощью Quartz? Вот связанная ссылка: Сохранение задания JavaQuartz


person matuda    schedule 24.06.2014    source источник
comment
Существует ли конечное число параметров, которые могут однозначно описать ваш поток? У вас есть база данных для использования?   -  person PM 77-1    schedule 24.06.2014
comment
Да, есть база данных для использования, а также уникальный идентификатор для каждой задачи. Вы предлагаете мне запрашивать БД при запуске сервера?   -  person matuda    schedule 24.06.2014
comment
Вам нужен постоянный пул потоков с возможностью повторного запуска определенного потока, если он не завершился. Если ваши потоки очень похожи с разницей только в некоторых параметрах, то вы можете сохранить эти параметры в базе данных. Проблема доли секунды, описанная ниже, все еще остается.   -  person PM 77-1    schedule 24.06.2014


Ответы (2)


Я считаю, что ваши требования невыполнимы, так как это вариант проблемы византийских генералов, которая доказуемо неразрешима. Выполняемый поток аналогичен атаке одного из генералов. Запись, необходимая для предотвращения повторного запуска потока, аналогична атаке другого генерала. Таким образом, ваше требование аналогично требованию, что либо оба генерала атакуют, либо ни один из них, невозможно выполнить.

Вы не можете избежать следующей основной проблемы.

  1. Нить заканчивается.

  2. Вы записываете, что нить завершена, и вы больше не выполняете эту работу.

Что, если система выключится после 1, но до 2?

Вам нужно переосмыслить проблему и свои требования. Упрощенная версия, которую вы представили, не может быть решена, как было задано.

person David Schwartz    schedule 24.06.2014
comment
Спасибо за ваши комментарии @david Я согласился, что пример кода не совсем то, что у меня есть в моем приложении. Обновлю эту ветку, если найду какое-то решение или переделаю... - person matuda; 24.06.2014

Я решаю эту проблему немного сложнее

  • Я использую вызываемый интерфейс, чтобы отслеживать свой «поток».

  • Добавьте ShutdownHook 1

Часть 1. Создание вызываемого объекта

Set<Future<Boolean>> set = new HashSet<Future<Boolean>>();

общедоступный сервер HttpServer = null; общедоступный HttpContext hc = null;

public void myServerInitiator() throws IOException {
    server = HttpServer.create(new InetSocketAddress(port), 0);
    hc = server.createContext("/test", new MyHandler());
    // create all the thread and start it here
    for(int i =0; i<5;i++)
       Callable<Boolean> callable = new MyDelegator ();
       Future<Boolean> future = pool.submit(callable);
       set.add(future);
    }
    ........
}

Часть 2: Добавляем крючок

public void myServerStop() throws IOException {
    Runtime rt = Runtime.getRuntime();
    rt.addShutdownHook(new Thread() {
          public void run() {
              // In real life this might close a Connection or something.
              System.out.println("Running shutdown hook and closing all connection");
              if(server != null) {
                  server.removeContext(hc);
                  server.stop(1);                     
              }
              // get all the "thread object" and do whatever you want based on the state
           for (Future<Boolean> future : set) {

             }
          });
}
person dgm    schedule 24.06.2014