繁体   English   中英

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

[英]java methods and race condition in a jsp/servlets application

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

  1. doSomething() 不是staic方法 ,它将值写入数据库。
  2. doSomething()静态方法,但它不会将值写入数据库。

我注意到我的应用程序中的许多方法可能会导致竞争条件或脏读/写。 例如,我有一个轮询系统,并且对于每个投票操作,某个方法将更改该轮询的单个单元格值,如下所示:

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

JSP / Servlets应用程序会自己解决这些问题,还是我必须自己解决所有问题?

谢谢..

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

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

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

Servlet API当然不会神奇地使并发成为非问题。

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

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

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

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

情况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队列来简单地记录“投票”。 让一些其他进程从队列中获取投票并添加它们。 您不会以这种方式立即向选民提供反馈,但您将用户的体验与实际(在类似场景中)相当复杂的处理分离。

我认为你的问题的最佳解决方案是使用“synchronized”关键字和wait / notify之类的东西!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM