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(); 
    } 
}