Mutualising multi-threaded calls to EJB from Servlet
The concurrency looks complete to me in the sense that I cannot see any places it can fail, or block significantly. The static LOCK and Future make sense. The getLocalRosterRequest itself is technically correct in the sense that it returns the right results, without logic problems. There is no need for the double-check locking though. It saves nothing, and solves nothing, other than creating two separate lock points.

Additionally, methods should not return concrete-types when interface-types would be available. Your method (and Future should be of type List&lt;String&gt; and not ArrayList&lt;String&gt;

Your code pulls the writeLock() from the LOCK, and locks on that. There are only two places where you use LOCK (one in the call, the other in the get). Neither of them need a sub-lock of the LOCK, they can both operate on the LOCK itself.

Your code would be simpler, and slightly faster, as simply:

  private Future&lt;List&lt;String&gt;&gt; getLocalRosterRequest() {
        LOCK.lock();
        try {
            if (currentRosterRequest == null) { //if there isn't a current request, create a new one
                currentRosterRequest = ROSTER_FETCH_EXECUTOR_SERVICE.submit(ROSTER_FETCH_TASK);
            }
            return currentRosterRequest; //return a reference to the current request
        } finally {
            LOCK.unlock();
        }
  }


and then, in the call method, you would have:

      try {
          return rosterEJB.getRoster();
      } finally {
          //one way or another the roster request has terminated
          LOCK.lock();
          try {
              //clear out the static variable
              MyServlet.currentRosterRequest = null;
          } finally {
              LOCK.unlock();
          }
      }