在两个 liferay portlet 中,每两个 Spring 应用程序上下文中的静态易失性字段在 class 内具有不同的值

Static volatile field has different values within class per two Spring application contexts in two liferay portlets

此 class 在项目 I 中定义。项目 II 和项目 III 都将项目 I 作为依赖项。

public class A {

    private static volatile int schemaVersion = -1;

    public synchronized void incrementSchemaVersion() {
        value++;
    }

}

Project IIproject III 有 Spring 应用程序上下文,它们创建 liferay portlet。

我希望当在项目 II 应用程序上下文中工作的线程增加 schemaVersion 的值时,该值对于也在项目 III 应用程序上下文中工作的任何其他线程都是可见的。

事实并非如此。

我有代码可以增加项目 II 中模式版本的值。这种变化发生了,我检查过。稍后,当项目 III 进来并尝试检查 schemaVersion 值时,它仍然是 -1。

spring 是否对静态值做了一些奇怪的事情?静态值不应该是每个 JVM 一个吗?

据我所知,发生这种情况的唯一方法是 class A 分别加载,为每个项目使用不同的 classloader。在这种情况下,您最终会得到 A 的三个不同副本,每个副本都有自己的 static 字段,称为 schemaVersion.

对一个的更改不会反映在另一个中。

您需要通过放入一些东西来检查这三个项目的 classloader 是否相同。你可以使用

之类的东西进入 classloader
ClassLoader loader = A.class.getClassLoader();

从三个项目开始做,看看你是否最终得到相同的 loader

请注意 getClassLoader() 可以 return null,在这种情况下,这意味着 class 是由 bootstrap class 加载的装载机。