cancel
Showing results for 
Search instead for 
Did you mean: 

A.E: race conditions because no synchronization possible?

udoderk
Champ in-the-making
Champ in-the-making
Hi everybody,
i look at org.activiti.explorer.ExplorerApp class

public class ExplorerApp extends Application implements HttpServletRequestListener {
 
  private static final long serialVersionUID = -1L;

  // Thread local storage of instance for each user
  protected static ThreadLocal<ExplorerApp> current = new ThreadLocal<ExplorerApp>();
 
  protected String environment;
  protected UserCache userCache;
  protected MainWindow mainWindow;
  protected ViewManager viewManager;
  protected NotificationManager notificationManager;
  protected I18nManager i18nManager;
  protected AttachmentRendererManager attachmentRendererManager;
  protected FormPropertyRendererManager formPropertyRendererManager;
  protected VariableRendererManager variableRendererManager;
  protected LoginHandler loginHandler;
  protected WorkflowDefinitionConversionFactory workflowDefinitionConversionFactory;
  protected ComponentFactories componentFactories;

and think about whether race conditions  (RCs) are possible, beacause no synchronization for protected varibales exist. Only ThreadLocal is used to get a access (for each registered thread) on components of ExplorerApp.

Theoretically RCs should not exist after call of the "activiti-explorer" uri in browser, beacuse:
At first time the org.activiti.explorer.servlet.ExplorerApplicationServlet will be created.
That Servlet will be injected into first thread, that process the servlet.
The method "service() will be called. Within of that method the application will be created using spring's WebApplicationContextUtils


  @Override
  public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);
    applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletConfig.getServletContext());
  }

  @Override
  protected Class< ? extends Application> getApplicationClass() throws ClassNotFoundException {
    return ExplorerApp.class;
  }

  @Override
  protected Application getNewApplication(HttpServletRequest request) {
    return (Application) applicationContext.getBean(ExplorerApp.class);
  }

The WebApplicationContextUtils should be used same thread context, that was created during GET-Request.
If the second GET-Request occurs, so the thread from thread poll will be used. (That may be new thread).
Thus, the application will be loaded in another thread context.

So quasi single thread model for each user exists…

But this is only theory…

Thanks for your replays!
1 REPLY 1

frederikherema1
Star Contributor
Star Contributor
That makes sense… if we add "load-on-statup" parameter in web.xml, the web-application-context will be initialize when he container starts so the servlet init will be called once before the servlet actually starts serving.

The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive 128 integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.

However, I imagine the most containers to have a mechanism that prevents the init() to be called twice for the same servlet (when multiple incoming HTTP-calls are done to it when not yet initialized). This is a servlet-specific issue and is independent of the way we handle the thread-local storage of the ExplorerApplication.