0

我正在赶最后期限工作,我现在正在出汗。从过去几天开始,我一直在解决一个问题,现在是时候大声疾呼了。

我有一个应用程序(我们称之为“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 类当我调用 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();
}

}

4

3 回答 3

0

会不会是这个类是从不同的类加载器加载的?

于 2009-08-03T07:57:15.307 回答
0

首先删除所有“实例”。: 你不需要它们。serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet :是一样的。

然后你会意识到你的方法 copyAllMasterData 没有做任何事情。它只是从一个集合中获取元素并将它们放在同一个集合中。将数据放入集合(例如 serviceNameSet)的唯一位置是在 add 方法中,我看不到它(add 方法)在任何地方被调用。

于 2009-08-14T15:38:01.390 回答
0

经过大量研究和仔细研究设计,这似乎是 Weblogic 类加载器的问题。我的产品有 6 个不同的应用程序,不保证同一个调用加载程序会加载所有应用程序。

因此,在上述情况下,实际数据在由 ClassLoader_X 加载的类中更新,访问由具有 ClassLoader_Y 的类完成。显然,数据在类加载器之间是不透明的。所以,我总是有同一个类的不同实例,访问器类中的数据总是空的。

一旦我将数据创建和消费类都移动到单个应用程序/Jar 中,一切正常。我没有更改任何上述代码。

于 2009-11-04T21:02:23.690 回答