Tomcat中的Servlet并发/同步?

时间:2009-10-06 21:30:28

标签: java servlets concurrency

是否有推荐的方法来同步碰巧竞争相同资源的Tomcat Servlet实例(如文件或非ACID的MongoDB等数据库)?

我熟悉线程同步,以确保两个Java线程不会同时访问同一个Java对象,但不能访问JRE外部存在的对象。

编辑:我只运行了一个Tomcat服务器。这是否意味着不同的JVM,我不确定(我认为它是相同的JVM,但可能是不同的线程)。


编辑特定用例(但我一般都在问这个问题):

Tomcat服务器充当文件存储,将原始文件放入目录,并使用MongoDB存储元数据。除了并发问题,这是一个非常简单的概念。如果存在两个并发请求来存储同一个文件,或者同时管理同一个对象上的元数据,我需要一种解决方法,我不知道如何。我想最简单的方法是以某种方式序列化/排队请求。有没有办法在Tomcat中实现排队?

5 个答案:

答案 0 :(得分:3)

通常,您的各种servlet将在同一个JVM中运行,如果不是,您应该能够配置您的servlet运行器,因此就是这种情况。所以你可以安排他们看一些中央的共享资源管理器。

然后对于实际的gubbinry,如果普通的旧同步不合适,请查看Semaphore类的示例(链接是我之前写的教程/示例的一部分,以防它有用),它允许您处理资源的“池”。

答案 1 :(得分:3)

如果您正在运行一个tomcat服务器并且所有servlet都在一个上下文中,则始终可以在该上下文类加载器上存在的java对象上进行同步。如果您正在运行多个上下文,则“同步对象”不能驻留在任何特定上下文中,而是需要驻留在所有上下文共享的更高级别。您可以在tomcat 6.0文档here中使用“common”类加载器将“同步对象”放在那里,然后在所有上下文之间共享。

答案 2 :(得分:2)

我有两种情况,如果您希望在同一JVM中访问用于文件编辑的公共资源,则可以在Java函数中使用“synchronized”。如果不同的JVM和其他没有Java线程访问公共资源,您可以尝试使用手动文件锁定代码为队列中的每个线程优先级编号

对于数据库,我认为没有并发问题。

答案 3 :(得分:1)

您的外部资源将以某种方式由Java对象(例如java.io.File)表示。如果需要,您始终可以在该对象上进行同步。

当然,这意味着必须在servlet实例之间共享所述对象。

答案 4 :(得分:1)

你正在寻找麻烦的IMO。有理由发明数据库和共享文件系统之类的东西。尝试使用一些Singleton类或信号量编写自己的版本会很快变得难看。找到一个能够为您完成此任务的存储解决方案,并为您节省很多麻烦。