java - Google App Engine标准+ Firebase数据库

标签 java multithreading google-app-engine servlets firebase-realtime-database

我有一个Google App Engine + Firebase数据库后端架构。我正在编写一个servlet,它应该从数据库中获取一些值,进行计算并使用这些值构建响应。问题在于onDataChange()方法是异步调用的。首先,我将介绍我的代码,然后继续:

//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请求。这就是为什么我不能使用synced(this)的原因,因为它将停止服务器获得的所有客户端响应的同步线程(我只需要停止1个主线程,仅停止一个请求的主线程)。如何正确摆脱方法的异步性?

最佳答案

我自己进行了一些研究,发现了一个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();
    }
}

关于java - Google App Engine标准+ Firebase数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45691269/

相关文章:

java - 使用执行器处理 Java 中流的子流

c - 从多个socket读取 : single thread with select vs. 多线程读取

c - 从另一个线程访问主线程的局部变量

google-app-engine - Google App Engine (java) 的集成测试

java - 如何在 Java 中获取文件的文件扩展名?

java - 该程序打印所有团队的名称,而不仅仅是破坏规则的人

database - 是否有任何支持多线程的本地数据库?

google-app-engine - Google 应用引擎 - 本地开发服务器时区

android - 如何修复使用 Jackson/Gson 库解析的不准确的日期时间(分钟)?

java - 如何防止客户端在 Android 库中看到内部私有(private)类?