保持HTTP servlet请求线程以重新加载业务配置对象

时间:2015-08-22 07:44:08

标签: java servlets thread-safety queue thread-synchronization

我需要在http servlet中运行时热加载或重新加载业务配置/对象。

通过在servlet Config期间读取文件来生成

init()对象。我需要在更改/更新文件时重新加载此对象。

public void init() {
    Config config = initializeConfigFile();
}

任务1 将是一个线程定期监视文件内容,如果更改,则从更改的文件重新创建配置对象..我认为这可以通过在文件内容上使用md5之类的哈希来实现..检查新哈希是否改变..

public void run() {
    // Read file
    // Generate hash of file contents
    // Compare with previous hash
    // If different set a flag to hold threads
    // configFileChanged = true;
}

任务2 保留请求线程,直到创建新的配置对象。由于这在运行时发生,可能有请求线程已经访问旧的配置对象,我不能只是交换配置对象,因为这可能会产生意外的行为。所以我需要等到已经访问旧配置的所有线程完成。

所以我需要有关任务2的建议..我没有探索过很多基于java高级线程和基于队列的API' s 现在考虑一些持有请求线程的队列。

public void doGet(HttpServletRequest req, HttpServletResponse resp) {
    if (configFileChanged) {
     synchronized (ActionServlet.class) {
        while (configFileChanged) {
            if (queue.isEmpty) {
                config = initializeConfigFile();
                configFileChanged = false;
            } else {
               sleep(2000);
            }
        }
    }
    }
    queue.insert(Thread.currentThread());
    // perform task using config object
    queue.remove();
}

同时建议任务1的即兴创作,如果有的话......

谢谢..

1 个答案:

答案 0 :(得分:0)

这两项任务都很糟糕:

对于任务1:
检查文件常规不是一个逻辑过程,而您可以有一个观察者/监视器,换句话说,一旦文件被更改,检查新配置(文件监视器使用java.nio.file

对于任务2:
如果且未配置/覆盖容器以为每个请求创建新实例。 - >默认/ std行为是拥有Servlet的一个对象,并通过一个线程为每个请求调用实例,因此synchronized void reload()方法会有所帮助。
reload()方法运行期间,因为它锁定了Servlet对象,所有新请求将一直保持到reload()完成它的工作。

public void doGet(HttpServletRequest req, HttpServletResponse resp) {
 //servlet business
}
//the reload is called by the file monitor
//The synchronized method will hold all new requests
synchronized void reload(){/*applying new configs*/}

除了让文件(外部)观察者看起来不安全和合乎逻辑之外,我建议有一个外部应用程序监视文件并通过调用servlet(可能是/friends/reload_config)通知web上下文,其中有一个servlet映射到/friends/reload_config,将调用reload()方法。

您可以在/friends/reload_config servlet中检查请求ip,以确保请求是由本地应用程序生成的(而不是来自网络)