java:竞争条件 - 有没有办法确保几行代码一起执行?

时间:2010-02-08 14:25:40

标签: java race-condition

我有一个注册页面,它接收令牌广告解析它们并在参数适用时登录用户。

在我检查令牌的时间到我从数据库中删除令牌的时间之间,另一个用户可以使用相同的令牌登录。有没有办法确保在没有干扰的情况下执行特定范围的代码行,所以我不会遇到竞争条件问题?

感谢

更新

我有两台服务器。

  1. apache tomcat 6
  2. red5 v0.9(免费的基于java的Flash媒体流和通信服务器)
  3. 我正在为Facebook写一个游戏应用程序。

    游戏本身是用adobe flash builder 2编写的。

    游戏本身将使用red5服务器提供。问题是red5没有收到请求和响应头,因此无法检索用于从Facebook获取信息的会话信息。

    解决用户连接到tomcat服务器的问题,该页面检查会话中的facebook相关信息并使用tinyFBClient连接到facebook,并将信息存储在mysql db(用户详细信息)中,以便制作确保这个用户是将要连接到red5的用户。

    创建令牌后。 tomcat页面显示一个对象HTML元素,以显示相关的SWF文件(游戏文件)。 tomcat页面将令牌传递给该SWF文件。加载SWF文件后,它会获取该令牌并使用它连接到red5并找到用户信息。

    我希望这些描述可以帮助您了解我的需求。 感谢您的支持!

5 个答案:

答案 0 :(得分:3)

您可以同步代码块,这样一次只能有一个线程执行它。但是,这似乎不是一个非常好的解决方案,因为它会降低您的应用程序速度。您希望同时登录多个用户。

如何创建令牌?如果您要在服务器端生成它们以响应用户登录,则一个用户不应该能够使用其他用户的令牌。

答案 1 :(得分:2)

听起来你需要一个同步的方法/块:

请参见此处(同步方法)

http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html

小心不要过度烹饪!同步太多会导致瓶颈!

答案 2 :(得分:2)

您可以使用Lock对象。

使用Lock对象优于更原始的synchronized blocks和方法。

答案 3 :(得分:2)

我不确定你为什么要为登录创建令牌。您的问题似乎暗示此令牌位于数据库而不是内存中。如果是这样,同步和互斥锁将无法提供帮助,您需要的是使用“select for update”锁定数据库记录。

也许这会产生很多不相关的复杂性,但为什么要创建一个令牌来进行登录?每次登录时,我只是从屏幕或传入表单中收集用户ID和密码,检查数据库是否有效,如果是,请让用户进入。您需要什么令牌?

答案 4 :(得分:1)

你说你“从数据库中删除令牌”。数据库是SQL数据库吗?如果是这样,那么您可以使用交易来避免竞争条件。它看起来像这样:

  1. 创建唯一的会话ID,例如UUID sessionID = UUID.randomUUID();
  2. 开始交易
  3. 从DB中删除与请求中的任何令牌匹配的任何令牌,例如
    DELETE FROM Tokens WHERE TokenID = < requested-token>
  4. 获取受影响的行数
  5. 如果受影响的行数正好为1,则令牌有效。创建一个会话,例如
    插入会话VALUES(sessionUUID,userID,loginTime,...)
  6. 提交交易
  7. 现在,如果登录成功(即受影响的行数正好为1),请向客户端发送包含会话ID的cookie。