【问题标题】:Synchronization required for multithreaded GAE apps?多线程 GAE 应用程序需要同步吗?
【发布时间】:2013-02-08 18:27:40
【问题描述】:

如果您将ThreadManager.currentRequestThreadFactory()ExecutorService 结合使用,Google App Engine 允许您创建线程。所以,为了让同一个前端实例同时处理多个 servlet 请求,我打算编写如下代码:

public class MyServlet implements HttpServlet {
    private RequestDispatcher dispatcher;

    // Getter and setter for 'dispatcher'.

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        MyResponse resp = dispatcher.dispatch(request);

        PrintWriter writer = response.getWriter();

        // Use the 'resp' and 'writer' objects to produce the resultant HTML
        // to send back to the client. Omitted for brevity.
    }
}

public class RequestDispatcher {
    private ThreadFactory threadFactory =
        ThreadManager.currentRequestThreadFactory();

    private Executor executor;

    // Getters and setters for both properties.

    public MyResponse dispatch(HttpServletRequest request) {
        if(executor == null)
            executor = Executors.newCachedThreadPool(threadFactory);

        // MyTask implements Callable<MyResponse>.
        MyTask task = TaskFactory.newTask(request);

        MyResponse myResponse = executor.submit(task);
    }
}

所以现在我相信我们有一个设置,每个前端都有一个 servlet,可以同时接受多达 10 个(我相信这是 GAE 允许的最大值)请求,并处理所有这些都同时没有阻塞。所以首先,如果我误用了ThreadManager 并且没有正确使用它,或者如果我对这种并发行为的设置不正确,请先纠正我! p>

假设我或多或少地步入正轨,我对 Google App Engine 线程如何利用 MyTask 对象下的对象树有一些与并发相关的担忧。

MyTask 可调用对象负责实际处理 HTTP 请求。在 EJB 领域,这将是“业务逻辑”代码,它执行以下操作:(1) 将消息放入队列,(2) 访问 Google 数据存储以获取数据,(3) 将内容保存到缓存等。也就是说,当call() 方法由Executor 执行时,它会生成一个大的“对象树”(许多后续的子对象)。

我是否必须使从MyTask#call 内部创建的每个对象都是线程安全的?为什么或为什么不?提前致谢!

【问题讨论】:

    标签: java multithreading google-app-engine concurrency


    【解决方案1】:

    您不需要所有这些来使实例能够同时处理多个请求。如果您在处理单个给定请求时需要并行执行多个任务,GAE 允许您生成线程。

    它可能很有用,例如,如果您需要同时联系多个外部 URL 以获取响应给定请求所需的信息。这将比按顺序联系所有 URL 更有效。

    【讨论】:

    • 感谢@JB Nizet (+1) - 已注意到。那么,在这种情况下,假设我确实有一个像你提到的用例(一次而不是按顺序点击多个 URL)。我上面的代码 sn-ps 是否正确? 更重要的是,我是否必须使源自call() 方法的整个对象树成为线程安全的?这是我问题的根源。再次感谢!
    • 没有。如果对象同时被多个线程访问,则需要使对象成为线程安全的。你的任务对象只能被一个线程访问。
    • 如果我为每个MyTask 注入Buzz 对象的相同全局单例实例(从TaskFactory#newTask 内部)会怎样?我是否仍然清楚,还是需要使Buzz 线程安全?再次感谢您迄今为止的所有帮助。
    • 是的,它需要是线程安全的。共享状态必须是线程安全的。我建议你读一本关于多线程的好书,因为这是一个非常复杂的事情,你不能通过在 StackOverflow 上提问来学习它。我建议由 Brian Goetz 撰写的 Java Concurrency in Practice
    • 我也在读 Brian Goetz,同一本书,我只能赞同。阅读。另外,请查看有关 web.xml 的 google 文档,您必须在其中通过设置 threadsafe=true 来启用请求的多线程处理。
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 2020-03-15
    • 2018-12-17
    • 2012-10-22
    相关资源
    最近更新 更多