2

我有一个Google应用引擎+ Firebase数据库后端架构。我正在编写一个servlet,它应该从数据库中获取一些值,进行计算并用此值构建响应。问题是onDataChange()方法是异步调用的。起初,我想介绍一下我的代码,然后继续:Google应用引擎标准+ Firebase数据库

//Here I initialize a listener that would be called when the onDataChange() 
//method is finished to make the code synchronous. 
    responseReadyListener = new ResponseReadyListener() { 
      @Override 
      public void onResponseReady() { 
       responseReady[0] = true; 
       synchronized (MyServlet.this) { 
        MyServlet.this.notify(); 
       } 
      } 
     }; 
     ref.addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
        //notify the main thread that the response can be sent 
        responseReadyListener.onResponseReady(); 
       } 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 
     //the loop that stops the main thread until onDataChange() finishes 
     while (!responseReady[0]) { 
      try { 
       synchronized (this) { 
        if (!responseReady[0]) { 
         this.wait(); 
        } 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

现在的问题,最近我看了,只有一个servlet实例被创建以响应HTTP请求。这就是为什么我不能使用synchronized(this),因为它会停止服务器获取的所有客户端响应的同步线程(我只需要停止一个主线程,只有一个请求的主线程)。如何正确摆脱方法的异步性?

+0

也许这线程可以给你一些输入https://stackoverflow.com/questions/42467781/how-would-i-return-a-firebase-custom-token-如果最新一代的最定制令牌/ 42473134#42473134 –

回答

0

我自己做了一些研究,发现一个类CountDownLatch。当你不能获得一个可运行的实例(当你不是你,但API创建一个线程)时,其他类如ExecutorService不适合,这正是我的情况。下面是它的用法的例子:

final CountDownLatch synchronizer = new CountDownLatch(N/*this number represents the nubmer of threads that should finish before continuation*/); 

    ref.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
       //another thread, countDown() says CountDownLatch that 
       //one thread has finished its work (N = N - 1). 
       synchronizer.countDown(); 
      } 
     } 
    }); 

    try { 
     //main thread. Await() method stops the thread until countDown() is 
     //called N times, then execution continues. 
     synchronizer.await(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
}