【问题标题】:GWT, Google App Engine, TimerTask or Thread in ServiceImpl throw exceptionServiceImpl 中的 GWT、Google App Engine、TimerTask 或 Thread 抛出异常
【发布时间】:2010-11-19 14:30:26
【问题描述】:

我正在使用 GWT 和 Google App Engine。我有一系列记录,我想每 30 分钟更新一次。 在 ServiceImpl 我有以下代码:

new Timer().schedule(new TimerTask(){
    @Override
    public void run() {
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        result = updateFeeds();
    }
}, 30000,Long.MAX_VALUE);

当我运行应用程序时,当我得到:

com.google.gwt.user.server.rpc.UnexpectedException:
Service method 'public abstract java.util.List org.joke.planet.client.FeedService.loadFeeds()' threw an unexpected exception:
java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThreadGroup)

在第一行或粘贴的代码处。

我的问题是如何让后台工作人员在 GWT+AppEngine 服务中工作?

【问题讨论】:

    标签: java google-app-engine gwt multithreading


    【解决方案1】:

    你不能 - 后台工作人员意味着一个线程,并且在 gae 中创建线程不起作用。

    您的任务的答案不是创建线程或后台工作者,而是使用这个http://code.google.com/appengine/docs/java/config/cron.html

    【讨论】:

      【解决方案2】:

      您不能使用 java.util.Timer,因为它会创建一个普通线程,这在 AppEngine 上是不允许的。但是,您可以使用 AppEngine Modules API 的后台线程工具,如下所述: https://developers.google.com/appengine/docs/java/modules/#Java_Background_threads

      请注意,您只能在手动扩展的实例上使用后台线程。在这个例子中,后台线程每 30 秒打印一条消息,永远:

      Thread thread = ThreadManager.createBackgroundThread(new Runnable() {
        public void run() {
          try {
            while (true) {
              System.err.println("Doing something!");
              Thread.sleep(30_000);
            }
          } catch (InterruptedException ex) {
          }
        }
      });
      thread.start();
      

      【讨论】:

        【解决方案3】:

        先生,您可以从 appengine 的新 ThreadManager 类中受益。

        https://developers.google.com/appengine/docs/java/backends/overview#background_threads

        使用 ThreadManager.currentRequestThreadFactory() 获取线程工厂,该工厂将在当前请求完成后立即中断生成的线程,并使用 ThreadManager.backgroundThreadFactory() 生成将持续多久的线程(但仅适用于后端)

        对于前端请求,建议跟踪您的线程,如果您希望它们在 appengine 的请求过滤器中断它们之前完成,请调用 thread.join()。

        【讨论】:

        【解决方案4】:

        另请参阅task queues

        【讨论】:

          【解决方案5】:

          问题不仅在 App 引擎中,而且通常在任何 Servlet 容器中。当一个在服务方法中时(你总是在 Servlet 容器中),你不能创建线程并做睡眠。

          在当今可扩展的服务世界中,thread.sleep 是一件坏事......

          【讨论】:

          • 这几乎是完全错误的。在普通的 Servlet 容器中,创建执行周期性操作的后台线程是完全可能的/理想的。您说 Thread.sleep 在请求线程上是错误的,但在后台线程上不是正确的。
          • 我不得不回应@Geoff,声称线程和 sleep() 对可伸缩性不利,这与情况完全相反。良好的睡眠对于最大化并发能力至关重要。如果您在单线程环境中运行, Thread.sleep() 是个坏主意。在其他任何地方运行,这是在您不需要它并且必须等待异步进程时放弃cpu时间的唯一方法。
          猜你喜欢
          • 2013-06-02
          • 2013-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-14
          • 1970-01-01
          • 2014-08-09
          • 2012-07-09
          相关资源
          最近更新 更多