Java 静态volatile字段在两个liferay Portlet中每两个Spring应用程序上下文的类中具有不同的值
此类在项目I中定义。项目II和项目III都将项目I作为依赖项Java 静态volatile字段在两个liferay Portlet中每两个Spring应用程序上下文的类中具有不同的值,java,spring,liferay,Java,Spring,Liferay,此类在项目I中定义。项目II和项目III都将项目I作为依赖项 public class A { private static volatile int schemaVersion = -1; public synchronized void incrementSchemaVersion() { value++; } } 项目II和项目III具有Spring应用程序上下文,它们创建了liferay Portlet 我希望当一个线程在projectii
public class A {
private static volatile int schemaVersion = -1;
public synchronized void incrementSchemaVersion() {
value++;
}
}
项目II和项目III具有Spring应用程序上下文,它们创建了liferay Portlet
我希望当一个线程在projectii应用程序上下文中工作并增加schemaVersion的值时,这个值对于任何其他同样在projectiii应用程序上下文中工作的线程都是可见的
事实并非如此
我有一段代码,它从ProjectII中增加模式版本的值。这种变化发生了,我检查过了。后来,当ProjectIII进入并尝试检查schemaVersion值时,它仍然是-1
spring对静态值有什么奇怪的作用吗?静态值不应该是每个JVM一个吗?据我所知,唯一可能发生这种情况的方法是使用不同的类加载器为每个项目分别加载类
a
。在这种情况下,您将得到A
的三个不同副本,每个副本都有自己的static
字段,名为schemaVersion
对其中一个的更改将不会反映在另一个中
您需要通过输入一些内容来检查这一点,以查看三个项目的类加载器是否相同。您可以使用以下内容访问类加载器
ClassLoader loader = A.class.getClassLoader();
从这三个项目中执行此操作,并查看是否最终使用相同的加载程序
请注意,getClassLoader()
可以返回null
,在这种情况下,这意味着该类是由引导类加载器加载的。您能否提供一个类加载器,以便更容易地测试您的类?您是否也可以在其中添加一些内容,以检查来自三个不同项目的类加载器的A
,看看是否使用了相同的类加载器?@LukeMelaia不幸的是,仅隔离所需的部分需要花费大量时间,我将不得不提供文件,否则您将不得不根据我发布的内容自己编写这些文件-这对任何人来说都将花费很长时间。这就是为什么我只求助于解释。如前所述,您需要三个具有依赖关系的项目。两者都有单独的应用程序上下文,引用项目I中的同一个应用程序上下文。II和III是liferay Portlet项目。在一个干净的liferay实例上部署II和III,一切就绪。你可以想象这样做需要一段时间。你能帮我找出,如何检查是否使用了相同的类加载器吗?@Ev0oD我已经添加了一些相关内容。似乎甚至没有必要尝试。这里,他们说每个portlet位于不同的类路径上——分别加载。我想这就解释了——类和整个库可能是重复的,并且存在于每个portlet钩子中。每个portlet插件都有自己的类加载器,因为它是一个独立的webapp。但是你可以在一个插件中有多个portlet——这将使用相同的类加载器。啊,好的。不过,我认为我不能将两个war项目部署到(或作为)一个portlet插件中。