Reputation: 62702
Here are the requirements for the problem:
I am trying to use the servlet filter below to solve the problem. and I have following questions.
package com.exmaple;
@WebFilter("/*")
public class InitFilter implements Filter
{
private volatile boolean initialized = false;
public void destroy() {
System.out.println("InitFilter.destroy()");
}
// is this method thread safe and will only execute the init code once
// and will cause all requests to wait until initialization code is executed
// thread code
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("InitFilter.doFilter()");
if (initialized == false) {
synchronized (this) {
// do expensive initialization work here
initialized = true;
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("InitFilter.init()");
}
}
Upvotes: 1
Views: 997
Reputation: 14810
I would approach it as a ServletContextListener
and run the initialization in the contextInitialized
method, as a separate thread, maybe using a FutureTask
as @fge suggests, or a newSingleThreadExecutor
rather than a pool.
Maybe something along the lines of...
public void contextInitialized(ServletContextEvent sce)
{
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run()
{
// Long running initialization code, or a call to it.
}
});
}
This avoids problems with synchronization and only runs the initialization once. (Once per Context)
In any case, doing this or a Filter, the rest of your program has to deal with initialization being incomplete.
Upvotes: 1
Reputation: 623
I recommend you to put your long-running initialization in a thread, like:
public void init() throws ServletException {
//Configure logging, app, pool ...
MyAppStarter.getInstance().start();
}
Upvotes: 0