Java 如何在J2EE EJB中创建互斥体

Java 如何在J2EE EJB中创建互斥体,java,multithreading,jakarta-ee,synchronization,Java,Multithreading,Jakarta Ee,Synchronization,我对J2EE非常陌生,如果这是显而易见的,我深表歉意。我必须解决一个糟糕的数据库设计,它的更新不能安全地并行完成。解决此问题的最简单方法(目前)是在方法调用周围放置互斥保护,以序列化其访问 我理解,您不能安全地在J2EE中的方法上使用synchronized关键字,因为容器可能会干扰。J2EE中是否有一种“受支持”的方法来在EJB中创建互斥体/信号量/锁,以确保对整个J2EE应用程序方法的访问是序列化的?尝试使用静态对象作为互斥体,例如: private static final Object

我对J2EE非常陌生,如果这是显而易见的,我深表歉意。我必须解决一个糟糕的数据库设计,它的更新不能安全地并行完成。解决此问题的最简单方法(目前)是在方法调用周围放置互斥保护,以序列化其访问


我理解,您不能安全地在J2EE中的方法上使用synchronized关键字,因为容器可能会干扰。J2EE中是否有一种“受支持”的方法来在EJB中创建互斥体/信号量/锁,以确保对整个J2EE应用程序方法的访问是序列化的?

尝试使用静态对象作为互斥体,例如:

private static final Object mutex = new Object ();

public void someMethod() {
    synchronized(mutex) {
        // do work that must be globally synchronous
    }
}

在方法本身上使用
synchronized
对您不起作用的原因是,Java EE容器可能会创建多个EJB实例,但标记为
synchronized
的方法仅在每个实例的基础上受到保护(每个实例一次只能有一个线程执行
synchronized
方法,但可以同时访问多个实例).

仅为了繁荣,java.util.concurrent都被批准在容器中使用。使用信号量进行阻塞将在单个容器中工作,但您需要更高级别的同步来保持集群中的同步。

因此我可以安全地假设J2EE容器中的静态对象在容器?我假设这在集群应用程序中不起作用,但如果不同的容器使用不同的类加载器来加载给定的类,这将失败。我不知道解决方案是什么,但我很确定不是这样。@ILMTitan这取决于您在何处声明静态互斥对象。它们不需要在insi中声明删除EJB类,这将避免多个类加载器的问题。在何处声明它们可能取决于特定的Java EE容器,因为不同的供应商可能会使用不同的策略,在不同的类加载器中多次加载哪些类。