【问题标题】:Detect concurrent access to a java object检测对 java 对象的并发访问
【发布时间】:2020-09-09 11:04:03
【问题描述】:

我有一个关于java并发访问的问题。

项目上下文如下:JSF 2.1; Richfaces 4、hibernate 3.6、spring 3.2、java 7。

我有一个表格,显示了几十万个文件夹(每个文件夹都是一个java对象),每个表格行都是一个动态链接,可以访问该对象(文件夹)的咨询或修改。

我的问题是:如何防止多个用户查看或编辑一个文件夹?

换句话说,您如何检测多个用户同时访问文件夹(对象 java)?

我知道使用方法同步这个词可以防止并发访问,但我想检测并发访问以警告其他用户或其他用户文件夹(对象 java)已经打开,我们必须等待它关闭。

谢谢

【问题讨论】:

  • 首先,你需要把你试过的东西放上去。
  • 您能否详细说明当其他用户被告知当前正在同步方法中执行哪个线程时您想做什么?如果他们试图访问同步块,他们无论如何都会被阻止。这本身不是被“告知”其他人正在访问数据吗?
  • 我想我的解释不太清楚,想象一个 Web 应用程序,其中有几个具有不同个人资料的经理访问该应用程序进行咨询或修改(他们的个人资料允许),我只是想显示一个消息警告其他管理员他们尝试打开的文件夹正忙(由其他管理员打开),他们稍后再试。一次只能访问一位经理。我希望这次我清楚了。感谢您的帮助。
  • 任何一个java对象,你怎么知道有几个连接到应用程序的用户正在咨询或修改它?
  • @ChungYang 如果他们尝试访问同步块,他们无论如何都会被阻止。这本身不是“知情”吗?线程无法知道它被阻塞,等待输入synchronized 语句。事实上,在最终获得进入许可之前,线程无法执行任何操作。你能做的最好的就是在进入之前和之后立即拍摄实时时钟的快照,然后根据测量的时间差,线程可以猜测它是否有被屏蔽了。

标签: java concurrency jsf-2


【解决方案1】:

同步和所有其他锁定/阻塞方法只会阻止代码内的并发访问。

它不会阻止 2 个用户同时编辑同一个“事物”。这是您必须自己放入代码中的内容。

有两种最常见的方法来实现这一点:

  • 乐观锁定: 您假设,即使多个用户查看同一个项目,也不会同时有多个更改。因此,您仅在 SAVING 期间检查是否有并发修改。要实现这一点:
    • 问题中的对象需要一个时间戳,即上次修改的时间。 (任何人)
    • 一旦用户打开要查看的项目,您就会将该时间戳存储在会话上下文中。
    • 如果用户单击“保存”,您会将会话上下文时间戳与实际对象的时间戳进行比较。如果它们相同,则可以保存更改。如果在这期间对象已被修改,您需要显示一个错误,即它已被修改,并且如果不事先加载新的基值,则无法保存更改。
  • 悲观锁定: 您假设,每当用户查看对象时,都会发生变化。要实现这一点:
    • 有问题的对象需要一个 Int-Flag,它当前正在被编辑(任何人 - 标志 = 用户 ID)
    • 一旦第二个用户尝试加载该对象,您就会拒绝,因为当前有人正在编辑。
    • 这里的棘手部分是清理“锁”,如果编辑用户只是退出页面而没有通过应用程序方法“中止”。要处理这个问题,您需要定义一个 Lock-Timestamp,定义一些超时值(例如 30 分钟)并再做两次检查:
      • 编辑用户超过保存时的超时值?他不能再保存了。 (作为额外的,您可以允许以后保存,如果对象没有被其他人锁定,请使用 lock-user-id 来确定)
      • 对象已锁定,但锁定时间超过 30 分钟?第二个用户可以再次打开,并为自己申请 lock-user-id。

【讨论】:

    猜你喜欢
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多