我的基本程序是读取一个excel文件并将其存储在ConcurrentHashMap缓存中。这个ConcurrentHashMap将String作为键,并且每当修改excel文件时都必须更新一些值Object.ThisConcurrentHashMap以便加载/替换new /此地图中的旧值。
以下是我实现它的方式.ExcelDataFile不是单例,但想法是尽可能少的ExcelDataFile实例,如2或3.Excel文件将每隔15分钟频繁修改。
我的第一个问题是ExcelDataFile'getInstance()方法是否返回单例。
如果它不是单例,我的第二个问题是特定于MemoryLeaks.I我知道这个程序是弱一致的,但它可能导致内存泄漏,因为我没有在getInstance()方法中使用类级别锁。相反我依赖于volatile feilds (origData和excelDataFile(静态引用))。
我知道这永远不会是单例。在创建实例时,这里存在竞争条件。使用修改后的excel文件,即使在具有易失性静态引用和volatile origDate之后,两个线程最终会创建两个实例。当多个实例被创建时,静态ConcurrentHashMap也会导致内存泄漏。我选择了伪单例的这种易失性方式,因为指令不会被重新排序。但我不确定这是否比使用类级锁更好。并且还跳过类级别锁定ConcurrentHashMap(因为它没有意义)
public class ExcelDataFile {
public static String DATA_FILE_PATH ="/export/data.xlsx";
private static final Object CLASS_LOCK = new Object();
private static volatile long origDate;
private static volatile ExcelDataFile excelDataFile ;
private static ConcurrentHashMap<String,Object> dataLocalMap = new ConcurrentHashMap<String,Object>();
private ExcelDataFile(String dataFile){
ExcelDataReader reader = new ExcelDataReader(dataLocalMap);
reader.readExcelFile(dataFile);
}
public static ExcelDataFile getInstance(){
long newDate = getDate(DATA_FILE_PATH);
//0L if the file does not exist or if an I/O error occurs
if(newDate ==0){
dataLocalMap.clear();
}
if(excelDataFile == null || (newDate!=origDate)){
dataLocalMap.clear();
excelDataFile= new ExcelDataFile(DATA_FILE_PATH);
origDate = newDate;
}
return excelDataFile;
}
protected static long getDate(String fileName) throws SecurityException {
File file = new File(fileName);
long lastModifiedDate = file.lastModified();
return lastModifiedDate;
}
public Object getData(String key){
return dataLocalMap.get(key);
}
}
public class ExcelDataReader {
private static final String excelSheetName="excelsheet";
private ConcurrentHashMap<String,Object> map = null;
public ExcelDataReader(){
}
public ExcelDataReader(ConcurrentHashMap<String,Object> dataMap){
map = dataMap;
}
public ConcurrentHashMap<String,Object> readExcelFile(String excelFilePath){
//read the excel file and convert the rows into value objects and put them in the ConcurrentHashMap
Object obj = new Object();
map.put("TEST",obj);
return map;
}
}
将从多个线程调用此getInstance()
方法,并使用E xcelDataFile .getData()
方法获取缓存数据。
多个线程将使用以下代码
从此ConcurrentHashMap
获取数据
public static Object getCacheData(String key){
ExcelDataFile dataFile = ExcelDataFile.getInstance();
Object test = null;
if(null!=dataFile){
test =dataFile.get(key);
}
return test;
}