服务器关闭后保存并重新启动线程池

时间:2014-06-24 02:45:01

标签: java multithreading threadpool runnable threadpoolexecutor

我的应用程序有多个线程。如果服务器出现故障或重新启动,我想只执行那些未执行的线程。例如,在下面的代码段中:考虑在执行线程号1,4,2后服务器是否关闭。应用程序应在服务器重新启动后执行2,3和5个线程。

线程的任务本质上是ATOMIC。要么全部完成,要么没有任何反应。所以我必须以某种方式保存已执行的每个线程的状态。我怎么能这样做?

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 Job persistence

2 个答案:

答案 0 :(得分:0)

我相信你的要求是不可能的,因为这是拜占庭将军问题的一个变种,这个问题可证明是无法解决的。正在完成的线程类似于攻击的一个将军。确保线程不再运行所需的记录类似于其他一般攻击。因此,你的要求类似于要求两个将军攻击或两者都无法满足的要求。

您无法避免以下基本问题。

  1. 线程结束。

  2. 您记录线程已完成,以便您不再进行此项工作。

  3. 如果系统在1之后但在2之前关闭怎么办?

    您需要重新考虑问题和要求。您提出的过于简化的版本无法按要求解决。

答案 1 :(得分:0)

我以一种复杂的方式解决了这个问题

  • 我使用Callable Interface,以便跟踪我的“Thread”

  • 添加ShutdownHook 1

第1部分:创建可调用对象

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

public HttpServer server = null;    public 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) {

             }
          });
}