在两个 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 II 和 project 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 加载的装载机。
此 class 在项目 I 中定义。项目 II 和项目 III 都将项目 I 作为依赖项。
public class A {
private static volatile int schemaVersion = -1;
public synchronized void incrementSchemaVersion() {
value++;
}
}
Project II 和 project III 有 Spring 应用程序上下文,它们创建 liferay portlet。
我希望当在项目 II 应用程序上下文中工作的线程增加 schemaVersion 的值时,该值对于也在项目 III 应用程序上下文中工作的任何其他线程都是可见的。
事实并非如此。
我有代码可以增加项目 II 中模式版本的值。这种变化发生了,我检查过。稍后,当项目 III 进来并尝试检查 schemaVersion 值时,它仍然是 -1。
spring 是否对静态值做了一些奇怪的事情?静态值不应该是每个 JVM 一个吗?
据我所知,发生这种情况的唯一方法是 class A
分别加载,为每个项目使用不同的 classloader。在这种情况下,您最终会得到 A
的三个不同副本,每个副本都有自己的 static
字段,称为 schemaVersion
.
对一个的更改不会反映在另一个中。
您需要通过放入一些东西来检查这三个项目的 classloader 是否相同。你可以使用
之类的东西进入 classloaderClassLoader loader = A.class.getClassLoader();
从三个项目开始做,看看你是否最终得到相同的 loader
。
请注意 getClassLoader()
可以 return null
,在这种情况下,这意味着 class 是由 bootstrap class 加载的装载机。