Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache Servlet正在将数据写入另一个Servlet的outputstream_Apache_Servlets_Asynchronous_Tomcat7_Anonymous Class - Fatal编程技术网

Apache Servlet正在将数据写入另一个Servlet的outputstream

Apache Servlet正在将数据写入另一个Servlet的outputstream,apache,servlets,asynchronous,tomcat7,anonymous-class,Apache,Servlets,Asynchronous,Tomcat7,Anonymous Class,我有两个servlet,如下所示: public class ServletA extends HttpServlet { public void doGet(final HttpServletRequest request, final HttpServletResponse response) { // Kick off some async processing RequestQueue.putRequest(new Reque

我有两个servlet,如下所示:

public class ServletA extends HttpServlet {
  public void doGet(final HttpServletRequest request, 
                    final HttpServletResponse response) {
    // Kick off some async processing
    RequestQueue.putRequest(new RequestInfo(...), new FutureCallback<ResponseInfo> () {
      @Override
      public void completed(ResponseInfo responseInfo) {
        // Send some data to database
        TransactionManager.getInstance().create(...);
      }
    )};
    // Send response to client
    response.getWriter().println("ServletA: SUCCESS");
  }
}

public class ServletB extends HttpServlet {
  public void doGet(final HttpServletRequest request, 
                    final HttpServletResponse response) {
    // Use a CountDownLatch to force synchronous processing on an asynchronous construct
    final CountDownLatch completedSignal = new CountDownLatch(1);
    RequestQueue.putRequest(new RequestInfo(...), new FutureCallback<ResponseInfo> () {
      @Override
      public void completed(ResponseInfo responseInfo) {
        // Send some data to database, and send response to client
        TransactionManager.getInstance().create(...);
        response.getWriter().println("ServletB: SUCCESS");
        completedSignal.countDown();
      }
    )};
    completedSignal.await();
  }
}
公共类ServletA扩展了HttpServlet{
公共无效数据集(最终HttpServletRequest请求,
最终HttpServletResponse(响应){
//启动一些异步处理
putRequest(新的RequestInfo(…),新的FutureCallback(){
@凌驾
已完成公共作废(ResponseInfo ResponseInfo){
//向数据库发送一些数据
TransactionManager.getInstance().create(…);
}
)};
//向客户端发送响应
response.getWriter().println(“ServletA:SUCCESS”);
}
}
公共类ServletB扩展了HttpServlet{
公共无效数据集(最终HttpServletRequest请求,
最终HttpServletResponse(响应){
//使用倒计时闩锁强制异步构造上的同步处理
最终倒计时锁存器完成信号=新倒计时锁存器(1);
putRequest(新的RequestInfo(…),新的FutureCallback(){
@凌驾
已完成公共作废(ResponseInfo ResponseInfo){
//向数据库发送一些数据,并向客户端发送响应
TransactionManager.getInstance().create(…);
response.getWriter().println(“ServletB:SUCCESS”);
completedSignal.countDown();
}
)};
completedSignal.wait();
}
}
问题是,在重载情况下,调用ServletA的客户机有时会收到“ServletB:SUCCESS”作为响应

为什么会这样?如何修复


谢谢。

在ServletB中添加一个AtomicBoolean,以确保响应对象仅在修复问题后使用:

public class ServletB extends HttpServlet {
  public void doGet(final HttpServletRequest request, 
                    final HttpServletResponse response) {
    // Use a CountDownLatch to force synchronous processing on an asynchronous construct
    final CountDownLatch completedSignal = new CountDownLatch(1);
    // Use an AtomicBoolean to ensure response is only used once
    AtomicBoolean responseSent = new AtomicBoolean(false);
    RequestQueue.putRequest(new RequestInfo(...), new FutureCallback<ResponseInfo> () {
      @Override
      public void completed(ResponseInfo responseInfo) {
        // Ensure response has not already been sent
        if(!responseSent.compareAndSet(false, true)) { return; }
        // Send some data to database, and send response to client
        TransactionManager.getInstance().create(...);
        response.getWriter().println("ServletB: SUCCESS");
        completedSignal.countDown();
      }
    )};
    if(!completedSignal.await(60, TimeUnit.SECONDS)) {
      // Ensure response has not already been sent
      if(responseSent.compareAndSet(false, true)) {
        response.sendError(503);
      }
    }
  }
}
公共类ServletB扩展了HttpServlet{
公共无效数据集(最终HttpServletRequest请求,
最终HttpServletResponse(响应){
//使用倒计时闩锁强制异步构造上的同步处理
最终倒计时锁存器完成信号=新倒计时锁存器(1);
//使用AtomicBoolean确保响应只使用一次
AtomicBoolean responseSent=新的AtomicBoolean(false);
putRequest(新的RequestInfo(…),新的FutureCallback(){
@凌驾
已完成公共作废(ResponseInfo ResponseInfo){
//确保尚未发送响应
如果(!responseSent.compareAndSet(false,true)){return;}
//向数据库发送一些数据,并向客户端发送响应
TransactionManager.getInstance().create(…);
response.getWriter().println(“ServletB:SUCCESS”);
completedSignal.countDown();
}
)};
如果(!completedSignal.Wait(60,时间单位:秒)){
//确保尚未发送响应
if(responseSent.compareAndSet(false,true)){
响应。发送错误(503);
}
}
}
}