java:竞争条件 – 有没有办法确保几行代码一起执行?
我有一个注册页面,它接收令牌广告解析它们并在参数适用时登录用户。
在我检查令牌的时间到我从数据库中删除令牌的时间之间,另一个用户可以使用相同的令牌登录。 有没有办法确保执行特定范围的代码行而不会产生干扰,所以我不会遇到竞争条件问题?
谢谢
更新
我有两台服务器。
- apache tomcat 6
- red5 v0.9(免费的基于java的Flash媒体流和通信服务器)
我正在为Facebook写一个游戏应用程序。
游戏本身是用adobe flash builder 2编写的。
游戏本身将使用red5服务器提供。 问题是red5没有收到请求和响应头,因此无法检索用于从Facebook获取信息的会话信息。
解决用户连接到tomcat服务器的问题,该页面检查会话中的facebook相关信息,并使用tinyFBClient连接到facebook,并将信息存储在mysql db(用户详细信息)中,以确保这一点同一用户是要连接到red5的用户。
一旦创建了令牌。 tomcat页面显示一个对象HTML元素,以显示相关的SWF文件(游戏文件)。 tomcat页面将令牌传递给该SWF文件。 加载SWF文件后,它会获取该令牌并使用它连接到red5并找到用户信息。
我希望这些描述可以帮助您了解我的需求。 感谢您的支持!
您可以使用Lock对象。
使用Lock对象优于更原始的同步块和方法。
您可以同步代码块,这样一次只能有一个线程执行它。 但是,这似乎不是一个非常好的解决方案,因为它会降低您的应用程序速度。 您希望同时登录多个用户。
如何创建令牌? 如果您要在服务器端生成它们以响应用户登录,则一个用户不应该能够使用其他用户的令牌。
听起来你需要一个同步的方法/块:
请参见此处(同步方法)
http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html
另外,小心不要过度烹饪! 太多的同步会导致瓶颈!
我不确定你为什么要为登录创建令牌。 您的问题似乎暗示此令牌位于数据库而不是内存中。 如果是这样,同步和互斥锁将无法提供帮助,您需要的是使用“select for update”锁定数据库记录。
也许这会产生很多不相关的复杂性,但为什么要创建一个令牌来进行登录呢? 每次登录时,我只需从屏幕或传入表单中收集用户ID和密码,检查数据库是否有效,如果是,请让用户进入。您需要什么令牌?
你说你“从数据库中删除令牌”。 数据库是SQL数据库吗? 如果是这样,那么您可以使用交易来避免竞争条件。 它看起来像这样:
- 创建唯一的会话ID,例如
UUID sessionID = UUID.randomUUID();
- 开始交易
- 从DB中删除与请求中的任何令牌匹配的任何令牌,例如
DELETE FROM Tokens WHERE TokenID = - 获取受影响的行数
- 如果受影响的行计数恰好为1,则令牌有效。 创建一个会话,例如
插入会话VALUES(sessionUUID,userID,loginTime,…) - 提交交易
现在,如果登录成功(即受影响的行数正好为1),则向客户端发送包含会话ID的cookie。