jsp / servlets应用程序中的java方法和竞争条件

时间:2010-05-04 18:11:15

标签: java multithreading servlets race-condition

假设我有一个名为doSomething()的方法,我想在多线程应用程序中使用此方法(每个servlet都继承自HttpServlet)。我想知道是否有可能出现竞争条件以下情况:

  1. doSomething() 不是staic方法,它会将值写入数据库。
  2. doSomething()静态方法但不将值写入数据库。
  3. 我注意到我的应用程序中的许多方法可能会导致竞争条件或脏读/写。例如,我有一个轮询系统,对于每个投票操作,某个方法将更改该轮询的单个单元格值,如下所示:

    [poll_id |              poll_data        ]
    [1       | {choice_1 : 10, choice_2 : 20}]
    

    JSP / Servlets应用程序会自行解决这些问题吗,或者我必须自己解决所有问题?

    谢谢..

5 个答案:

答案 0 :(得分:4)

这取决于doSomething()的实施方式以及实际的实施方式。我假设写入数据库使用JDBC连接,线程安全。这样做的首选方法是创建ThreadLocal JDBC连接。

至于第二种情况,它取决于方法中发生的事情。如果它不访问任何共享的,可变的状态,那么就没有问题。如果是这样,您可能需要适当地锁定,这可能涉及向每个其他访问这些变量的锁添加锁。

(请注意,仅将这些方法标记为synchronized不会修复任何并发错误。如果doSomething()增加了共享对象上的值,则对该变量的所有访问都需要{{1因为synchronized不是原子操作。如果它像递增计数器一样简单,你可以使用i++。)

答案 1 :(得分:3)

Servlet API当然不会让并发成为非问题。

写入数据库时​​,它取决于持久层中的并发策略。悲观锁定,乐观锁定,最后胜利?当你“写入数据库”时,你需要决定如何处理,还有更多的事情要做。当两个人同时点击按钮时,你想要发生了什么?

将doSomething设为静态似乎对此问题没有太大影响。正在发生的事情是相关部分。它是修改静态变量吗?然后是的,可能会有竞争条件。

答案 2 :(得分:2)

servlet api不会为你做任何事情让你的并发问题消失。在servlet上使用synchronized关键字这样的事情是个坏主意,因为你基本上强迫你的线程一次处理一个,这会破坏你对多个用户快速响应的能力。

如果使用Spring或EJB3,则任何一个都将提供线程本地数据库连接以及指定事务的能力。你一定要看看其中一个。

答案 3 :(得分:2)

案例1,您的servlet使用一些访问数据库的代码。数据库具有您应该利用的锁定机制。这有两个重要原因:数据库本身可能会从其他读取和写入数据的应用程序中使用,但这还不足以让您的应用程序处理与自身竞争的问题。并且:您自己的应用程序可以部署到一个缩放的集群Web容器中,其中代码的多个副本在不同的计算机上执行。

因此,有许多标准模式可以处理数据库中的锁,您可能需要阅读悲观和乐观锁定。

servlet API和JBC连接池为您提供了一些有用的保证,这样您就可以在不使用Java同步的情况下编写servlet代码,前提是您的变量在方法范围内,在概念中

   Start transaction (perhaps implicit, perhaps on entry to an ejb)
   Get connection to  DB ( Gets you a connection from pool, associated with your tran)
   read/write/update code
   Close connection (actually keeps it for your thread until your transaction commits)
   Commit (again maybe implictly)

因此,您唯一真正的问题是处理数据库中的任何争用。以上所有这些都倾向于使用诸如JPA之类的东西更好地完成,但是在或多或少的情况下正在发生的事情。

案例2:静态方法,这可能意味着您现在将所有内容都保存在内存结构中。这(禁止某种远程调用)会影响单个JVM并管理您自己的锁定。如果您的JVM或机器崩溃,我猜您会丢失数据。如果你关心你的数据,那么使用数据库可能会更好。

或者,如何完全采用其他方法:servlet通过将消息写入持久性JMS队列来简单地记录“投票”。让一些其他进程从队列中获取投票并添加它们。您不会以这种方式立即向选民提供反馈,但您可以将用户的体验与实际(在类似情况下)非常复杂的处理分开。

答案 4 :(得分:0)

我觉得问题的最佳解决方案是使用“synchronized”关键字和wait / notify这样的东西!