我正在反对截止日期,我现在正在大汗淋漓。从过去几天开始,我一直在研究一个问题,现在是时候大喊大叫了。
我有一个应用程序(我们称之为“APP”),我有一个为APP编写的“PerformanceStatistics”MBean。我还有一个Singleton Data类(我们称之为“SDATA”),它为MBean提供了一些数据来访问和计算一些应用程序运行时的东西。因此,在应用程序启动期间,然后在应用程序生命周期中,我将向SDATA实例添加数据。因此,此SDATA实例始终具有数据。
现在,问题在于我无法访问PerformanceStatistics MBean中的任何数据或数据结构。如果我在添加数据时检查数据结构,则所有结构都包含数据。但是当我从MBean中调用这个单例实例时,我就有了空数据。
任何人都可以解释或暗示正在发生的事情吗?任何帮助将不胜感激。
我尝试了各种SDATA类是最终的,所有方法都是同步的,静态的等等,只是为了确保。但直到现在还没有运气。
另一个不幸的事情是,我有时会得到不同的“ServicePerformanceData”实例(即当我打印ServicePerformanceData.getInstance()时,它们在不同的时间是不同的)。不知道发生了什么。我在WebLogic服务器中运行此应用程序并使用JConsole。
单吨和数据访问方法的SDATA课程
public class ServicePerformanceData {
private Hashtable<String, ServiceExecutionDataCollector> serviceExecutionDataMap = new Hashtable<String, ServiceExecutionDataCollector>();
private HashMap<ServiceExecutionType, String> serviceTypeCountMap = new HashMap<ServiceExecutionType, String>();
private HashSet<String> serviceNameSet = new HashSet<String>();
private static final long DEFAULT_COUNT = 1;
private static final ServicePerformanceData INSTANCE = new ServicePerformanceData();
private Object SYNC = new Object();
private ServicePerformanceData() {
// don't allow anyone to instantiate this class
}
// clearly this must be a singleton
public static ServicePerformanceData getInstance() {
return INSTANCE;
}
public void add(ServiceExecutionDataCollector data) {
// I just add some runtime information to the data structures in this INSTANCE
synchronized (SYNC) {
if (INSTANCE.serviceTypeCountMap.containsKey(data.getServiceType())) {
String count = INSTANCE.serviceTypeCountMap.get(data.getServiceType());
INSTANCE.serviceTypeCountMap.put(data.getServiceType(), Integer.toString(Integer.parseInt(count) + 1));
} else {
INSTANCE.serviceTypeCountMap.put(data.getServiceType(), Integer.toString(1));
}
INSTANCE.serviceExecutionDataMap.put(data.getServiceName(), data);
INSTANCE.serviceNameSet.add(data.getServiceName());
}
}
public int getServiceTypeCount(ServiceExecutionType type) {
if (INSTANCE.serviceTypeCountMap.containsKey(type)) {
return Integer.parseInt(INSTANCE.serviceTypeCountMap.get(type));
}
return 0;
}
public Set getNameList() {
return INSTANCE.serviceNameSet;
}
// I am copying all the data just to make sure that data structures have data
public void copyAllMasterData() {
synchronized (SYNC) {
serviceExecutionDataMap.putAll(ServicePerformanceData.INSTANCE.serviceExecutionDataMap);
serviceNameSet.addAll(ServicePerformanceData.INSTANCE.serviceNameSet);
serviceTypeCountMap.putAll(ServicePerformanceData.INSTANCE.serviceTypeCountMap);
}
}
}
PerformanceStatistics MBean Class 当我调用像ServicePerformanceData .getInstance()这样的数据时,我在该结构中什么都没有。因此,我无法得到任何结果。
public class PerformanceStatistics
implements PerformanceStatisticsMBean {
public void completeExecutionDump() {
//
}
public int getexecuteSSCount() {
return ServicePerformanceData.getInstance().getServiceTypeCount(ServiceExecutionType.ADD);
}
public String executionInfo(String serviceName) {
// GIVES EMPTY LIST EVEN THOUGH THE ACTUAL instance HAS THE DATA
return ServicePerformanceData.getInstance().getExecutionInfo(serviceName.trim());
}
public String calledServicesArray() {
// servicePerformanceData DOES NOT CONTAIN ANY DATA EVEN THOUGH THE ACTUAL instance HAS THE DATA
ServicePerformanceData servicePerformanceData = ServicePerformanceData.getInstance();
servicePerformanceData.copyAllMasterData();
System.out.println("ServicePerformanceData.INSTANCE" + ServicePerformanceData.getInstance());
System.out.println(servicePerformanceData);
// GIVES EMPTY LIST EVEN THOUGH THE ACTUAL instance HAS THE DATA
System.out.println("Name List" + ServicePerformanceData.getInstance().getNameList());
return ServicePerformanceData.getInstance().getNameList().toString();
}
}
答案 0 :(得分:0)
该类是否从不同的类加载器加载?
答案 1 :(得分:0)
首先删除所有“INSTANCE”。 :你不需要它们。 serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet:它是一样的。
然后你会发现你的方法copyAllMasterData没有做任何事情。它只需要从一个集合中获取元素并将它们放在同一个集合中。将数据放入集合(例如serviceNameSet)的唯一位置是在add方法中,我看不到任何地方调用它(add方法)。
答案 2 :(得分:0)
经过大量研究并仔细研究设计,这似乎是Weblogic类加载器的一个问题。我的产品有6种不同的应用程序,不保证同一个调用加载程序加载所有应用程序。
因此,在上面的例子中,实际数据在ClassLoader_X加载的类中得到更新,并且类由ClassLoader_Y完成。显然,数据在类加载器中是不透明的。所以,我总是拥有相同类的不同实例,并且访问器类中的数据始终为空。
一旦我将数据创建和消费类都移动到单个应用程序/ Jar,一切都很好。我没有改变上面的任何代码。