由于Appengine不允许java多线程,我们如何才能将现有的多线程代码迁移到平台?
例如,我有以下代码:
Thread t = new Thread() {
public boolean alive = true;
public void run() {
while (alive) {
try {
Thread.sleep(5000);
getNewNotifications();
} catch (InterruptedException e) {
// Do nothing
} catch (IOException e) {
}
}
}
};
t.start()
函数getNewNotification()执行一些Rest / HTTP调用,可能包括一些可能无限期返回的其他进程。我已经阅读了Task Queue
是解决方案,但是我们如何将这个简单的代码转换为App引擎友好的代码?
如何使用任务队列实现上面的代码?例如,每隔五秒钟呼叫getNewNotifications()
。
该函数将从服务器获得一些结果,解析结果,然后根据结果执行它需要执行的活动/工作。
答案 0 :(得分:6)
您可以在java appengine中创建线程。
ThreadManager.createThreadForCurrentRequest(new Runnable(){...});
请参阅https://developers.google.com/appengine/docs/java/javadoc/com/google/appengine/api/ThreadManager
请求完成时,前端线程将被中断并终止,但是生成的后端线程可以运行很长时间。此外,当您捕获InterruptedException时,尝试做的不仅仅是什么;吞下这个例外会导致实例保持在线状态并且会花费更多的钱。
如果要使代码与Runnable和任务队列一起工作,只需实现Runnable和DeferredTask;两个接口都具有相同的方法签名。要调度延迟任务,只需执行QueueFactory.getQueue(“queueName”)。add(TaskOptions.Builder.withPayload(YourDeferredTask));
答案 1 :(得分:2)
您可能也对backends感兴趣。后端可以作为后台线程运行(实验性功能),因此它们可以像您以前一样用于轮询。但是,如果可能的话,使用任务可能更有效。如果通知来自您应用的其他部分,您可以直接创建任务,而不是创建通知。
答案 2 :(得分:1)
由于您需要定期执行代码,我建议cron。
只需将代码置于servlet的get(..)
方法中,将其映射到Url(通过web.xml
)并设置cron以定期调用此Url。
答案 3 :(得分:1)
根据您的预算(检查后端结算),您也可以使用Scheduled Tasks来实现这一目标。
您可以在cron.xml
文件中指定任务:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/getNewNotifications</url>
<description>Get new notifications every 5 minutes</description>
<schedule>every 5 minutes</schedule>
</cron>
</cronentries>
当然,您需要将一个servlet(或您正在使用的任何框架)映射到URL /getNewNotifications
。
您还应该确保URL is secure(通常您不希望用户调用该网址)。