code: @Override
      public synchronized void dispatch(ServletContext context, String path) throws IllegalStateException {
          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINEST)) {
              logger.entering(CLASS_NAME, "dispatch(ctx,path)",new Object [] {this,context,path});
          }
  
          if (!lockHeldByDifferentThread()){
              if (completePending) {
                  throw new IllegalStateException(nls.getString("called.dispatch.after.complete"));
              } else if (!dispatchAllowed){
                  throw new IllegalStateException(nls.getString("trying.to.call.dispatch.twice.for.the.same.async.operation"));
              }
  
              // PI28910, the effect of calling dispatch should not take effect until the calling
              // thread completes so it is too early to set asyncStarted to false
              // iExtendedRequest.setAsyncStarted(false);
  
              createNewAsyncServletReeentrantLock();
  
              //cancel timer inside lock so we don't kick off timeout events after we've decided to dispatch
              cancelAsyncTimer();
  
              WebAppRequestDispatcher requestDispatcher = (WebAppRequestDispatcher) context.getRequestDispatcher(path);
              dispatchRunnable = new DispatchRunnable(requestDispatcher, this);
              dispatchPending = true;
              dispatchAllowed = false;
              if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINEST)) {
                  logger.logp(Level.FINEST, CLASS_NAME, "dispatch(ctx,path)", "dispatching -->" + dispatching);
              }
              if (!dispatching) {
                  executeNextRunnable();
              }
          } else {
              if (WCCustomProperties.THROW_EXCEPTION_WHEN_UNABLE_TO_COMPLETE_OR_DISPATCH) {
                  throw new IllegalStateException(nls.getString("AsyncContext.lock.already.held", "Unable to obtain the lock.  Error processing has already been invoked by another thread."));
              }
          }
  
          dispatchURI = null;
  
          if (com.ibm.ejs.ras.TraceComponent.isAnyTracingEnabled() && logger.isLoggable(Level.FINEST)) {
              logger.exiting(CLASS_NAME, "dispatch(ctx,path)",this);
          }
      }
docs: we're okay to sync on the scheduling of the dispatch