当前位置: 首页 > 知识库问答 >
问题:

在单例会话Bean中管理并发访问

龚宏壮
2023-03-14

我与一位同事讨论了单例会话bean中的并发管理。根据我的理解,在阅读了Oracle文档之后,如果您取消了@ConcurrencyManagement注释,那么它默认为容器管理的并发。在文档中,它说明了以下关于容器管理的单例会话bean的内容:

html" target="_blank">javax.ejb.Lock注释和javax.ejb.LockType类型用于指定单例业务方法或@Timeout方法的访问级别。

如果singleton类上不存在@Lock注释,则默认的锁类型@Lock(LockType.WRITE)将应用于所有业务和超时方法。

现在,如果您使用@ConcurrencyManagement(ConcurrencyManagementType.bean)注释bean,那么您有责任确保bean的状态使用synchronized关键字和其他标准Java并发特性在所有客户机之间同步。文章甚至说:

允许使用bean管理的并发性创建单例的开发人员使用Java编程语言同步原语(如synchronization和volatile),以防止并发访问期间出现错误。

我在容器管理的并发性一节中没有看到这一点,这让我相信,如果你想自己同步东西,你需要用@ConcurrencyManagement(ConcurrencyManagementType.BEAN)注释这个类。

我的同事在我的豆子上看到这个注释时发表评论说:“伙计,你们这些家伙做了一些奇怪的事情”,这开始了这次讨论。

他的bean没有任何@ConcurrencyManagement注释,但他在整个类中使用synchronized关键字。我说他使用的任何更细粒度的同步都是毫无意义的,因为他的所有业务方法都有一个隐式的@Lock(LockType.WRITE)注释,对吗?这意味着,如果一个客户机调用他的一个方法,那么其他客户机就不能调用bean的任何方法,因此该方法中的显式同步将是无用的。

例如,对于在他的一个业务方法中的同步(myLock)中使用的一些锁myLock,不会有该锁的争用,因为这些方法本身是有效同步的。

如果我错了,请纠正我,但看起来他的方法基本上是这样的:

public synchronized void myMethod() {
    // do stuff
    synchronized (lock) {
        // modify mutable state
    }
}

public synchronized void myOtherMethod() {
    // do other stuff
    synchronized (lock) {
        // modify mutable state
    }
}

假设在这个单例会话bean中创建lock只是为了保护bean中的可变状态,那么在使用容器管理的并发时,它似乎没有任何用途。

提前感谢您对此的任何见解!

共有2个答案

满俊楠
2023-03-14

你是正确的,但这取决于他锁定的是什么,如果对象只绑定到那个单例,那么他确实是一个无所不知的人,实际上因为双重锁定而减慢了程序的执行。

勾裕
2023-03-14

一般来说,你所有的期望都是正确的。有一种小情况,您的同事的代码实际上可以使用同步原语。

如果存在ejb-jar.xml文件,它可以将并发管理设置为由bean管理。它看起来像这样:

<enterprise-beans>
    <session>
        <ejb-name>MySingletonEJB</ejb-name>
        <ejb-class>com.blah.MySingletonEJB</ejb-class>
        <transaction-type>Bean</transaction-type>
        ...
    </session>
...
</enterprise-beans>

自从EJB 3以来,这确实是一种糟糕的做事方式,注释肯定是首选的,因为配置与源是正确的。

 类似资料:
  • > 在EJB3.0及其之前的版本中,该问题是如何处理的? 如果它保留了客户端特定的会话状态,那么单个实例将拥有所有客户端(试图并发访问)的特定数据?它会安全吗?? 如果我们可以在其他会话bean中使用静态最终变量和静态初始值设定项块或静态方法来初始化它们(因为静态变量也是每个类的数据,而不是每个实例的数据),以便跨bean共享公共数据,那么单例会话bean需要什么呢? 在singleton中使用业

  • 问题内容: 这是我的工作方式 然后在 假设用户名是。然后,如果单击,将设置为Peter的用户对象,然后重定向到配置文件页面,该页面现在从中呈现信息。我只想使用创建相同的效果,因此想到了GET请求。所以我这样做 然后该方法就返回 剩下的就是创建一个servlet,捕获该,查询数据库以获取设置为重定向的对象。这是我的servlet 现在我有了,如何访问会话bean来查询数据库中的,然后访问受管Bean

  • 如果使用EJB3单例会话Bean,那么让ConcurrentHashMap状态变量-correct没有意义?我可以只使用一个由容器并发管理器管理的常规HashMap?

  • 问题内容: 在Node.js中管理会话变量的最佳方法是什么?有图书馆吗? 问题答案: 您可以使用以下命令轻松完成此操作: 连接: http : //senchalabs.github.com/connect/ Connects就像Ruby中的Rack。它为您提供了一个额外的层,您可以在其中“玩”身份验证,会话,Cookie等。 另一种选择是使用框架: Express.js: http://expr

  • 成功开发 Web 应用程序的难题之一是在一次用户访问,即会话期间,当用户在一个应用程序的页与页之间跳转的同时,维护用户信息。HTTP 是一种无状态协议,也就是说,Web 服务器将某页的每次访问都当作相互无关的访问来处理;服务器不保留前一次访问的任何信息,即使访问就发生在当前访问的几秒钟之前。正因为这种不记忆以前访问的特性使得编写联机目录之类的应用程序很困难,此类应用程序可能需要跟踪用户在目录的不同

  • 问题内容: 我有一个关于单例bean如何详细处理并发请求的问题。 我想要有关单例bean如何处理并发请求以及系统处理器如何看到这些请求的完整详细信息。 我已经研究了有关在线处理系统处理器中并发请求的问题。他们说处理器本身有一个调度程序,调度程序将决定处理哪个请求。 好的。如果假设我有多个核心处理器,那么调度程序如何处理并发请求? 谁能向我解释有关单例bean如何为JVM和系统中的并发请求提供服务的