数据量大时将数据存到内存中然后启动一个线程从内存中读取数据

如果遇到程序中的数据量大时,可以通过以下方法将其进行处理。
方法如下:
1 将得到的数据添加到内存中


2 启动一个线程(一直循环,不断的去扫描),专门读取内存的数据。


3 得到内存中的数据,进行下一步的操作(如添加到redis中或批量操作插入到数据库中)。


示例:
1 通过webservice时或者程序订阅每时每刻都会有大量的数据得到。
2 为了将数据保存到内存中。定义一个线程安全的类(单例模式+虚拟锁),类中定义一个list用来存取数据。
3 当程序中得到数据时,保存到该类的list中(通过虚拟锁达到线程安全)。
4 启动一个子线程(一直循环,不断的去扫描),专门去读取该类的list数据(每次读取1000条,可配置,读取list的方法也是通过虚拟锁达到线程安全)。
5 通过子线程得到了分批次的数据后。可以进行后续操作。如添加到redis中或批量操作插入到数据库中。


具体例子:
1 新建一个类,用来保存数据,将数据保存到内存中。
如:
   public class AisHistoryServiceFactory {


   public static AisHistoryServiceFactory instance = null;


   private static final Object uniqueLock = new Object();
   private static final Object objectLock = new Object();


   private List<AisInfo> aisInfoList = new ArrayList<AisInfo>();
   
   public static boolean flag_insert_hbase=false;//是否容许插入到hbase中
   
   public static AisHistoryServiceFactory getInstance() {
if (null == instance) {
   synchronized (uniqueLock) {
if (null == instance) {
   instance = new AisHistoryServiceFactory();
}
   }
}
return instance;
   }
   
   public boolean addAisInfo(AisInfo info) {
synchronized (objectLock) {
   if (isFull()) {
return false; // 内存list满,
   }
   //不需要解密
   AisInfo in = info;//getFromBase64(info);
   if (isNeedInfo(in)) {
if (null == aisInfoList) {
   aisInfoList = new ArrayList<AisInfo>();
}
if (!aisInfoList.contains(in)) {
   aisInfoList.add(0, in);
}
   }
   return true;
}
   }
   
   public boolean getAisInfo(List<AisInfo> list, int size) {
synchronized (objectLock) {
//            System.out.println("==== Get Info Size : " + size + " ====");
//            System.out.println("==== Info List Size Before Get  : " + aisInfoList.size() + "====");
   int countNum = 0;
   if(null != aisInfoList && aisInfoList.size() > 0){
for (int i = aisInfoList.size() - 1; i >= 0; i--) {
   AisInfo temp = aisInfoList.remove(i);
   list.add(temp);
   countNum++ ;
   if(countNum >= size){
//                        System.out.println("==== Info List Size After Get 1 : " + aisInfoList.size() + "====");
return true;
   }
   if(aisInfoList.size() <= 0){
//                        System.out.println("==== Info List Size After Get 2 : " + aisInfoList.size() + "====");
return true;
   }
   
}
   }
   return false;
}
   }
   
   private boolean isNeedInfo(AisInfo info) {

return true;
   }
   
   private boolean isFull() {
synchronized (objectLock) {
   int maxSize = SystemConfigFactory.getInstance().getSystemConfigInt(ConfigMacroDef.AIS_INFO_MAX_SIZE_WAN, 100); // 保存多少条AIS数据,
   maxSize = maxSize * 10000;
   if (null == aisInfoList && aisInfoList.size() > maxSize) {
return true;
   }
   else {
return false;
   }
}
   }
   
   
}


2 程序中得到原始数据后,将其保存到内存中。
如(某个类的普通方法):
   public void inserToAISH(AisInfo aisInfo_old) {
//改为加入到内存中
AisHistoryServiceFactory.getInstance().addAisInfo(aisInfo_old);
   }


3 程序中启动一个子线程(一直循环,不断的去扫描),用来读取内存中的数据。
如(最好放在启动的servlet中):
new AisHistoryServiceAisThread().start();


子线程类:
public class AisHistoryServiceAisThread extends Thread{


   /**
    * Description: <br> 
    *  
    * @author XXX<br>
    * @taskId <br> <br>
    */ 
   @Override
   public void run() {
// TODO Auto-generated method stub
//super.run();
try {
   Thread.sleep(10 * 1000);
   //System.out.println("开始启动读取数据的线程了");
   AIS_LOG.INFO("开始启动读取港航局历史轨迹的数据的线程了");
   while (true) {


AisHistoryAisFactory.getInstance().addAisDataToHistory();


Thread.sleep(10 * 1000);


   }
}
catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
}
   }


   
}


4 子线程会进行得到数据后的操作(分批次的读取数据,每次读取1000条。)。
如(普通类的普通方法,可以弄成单例的):
public class AisHistoryAisFactory {


   private int ais_num = 1000;


   private static AisHistoryAisFactory webServiceaisFactory = null;


   private static AisInfoService aisInfoService = (AisInfoService) SpringBeanFactory.getInstance().getBean(SpringBeanMacroDef.Service.AIS_INFO_SERVICE_IMPL);


   private static FerryService ferryService = (FerryService) SpringBeanFactory.getInstance().getBean(SpringBeanMacroDef.Service.FERRY_SERVICE_IMPL);


   private AisHistoryAisFactory() {

   }
   
   public static AisHistoryAisFactory getInstance() {
if (webServiceaisFactory == null) {
   webServiceaisFactory = new AisHistoryAisFactory();
   return webServiceaisFactory;
}
else {
   return webServiceaisFactory;
}
   }


   public void addAisDataToHistory() {
//WebServiceAisParseFactory aisParseFactory = WebServiceAisParseFactory.getInstance();
AisInfo aisInfo = new AisInfo();
AisInfo aisInfo_old = null;
List<AisInfo> aisDataList = new ArrayList<AisInfo>();
AisHistoryServiceFactory.getInstance().getAisInfo(aisDataList, ais_num);
int insert_num = 0;
int updata_num = 0;


/* 这是插入到redis中
for (int i = 0; i < aisDataList.size(); i++) {
   String aisData = aisDataList.get(i).toString();
    //System.out.println(aisData);
   aisInfo = aisParseFactory.parseAIS(aisData);
   
   if(aisInfo==null){//为空则不进行保存到redis中
System.out.println("出现解析gis数据错误,拼装为aisInfo时,返回的aisInfo为空,aisData="+aisData);
AIS_LOG.INFO("出现解析gis数据错误,拼装为aisInfo时,返回的aisInfo为空,aisData="+aisData);
   }else{//增加操作,放入redis库
RedisFactory.getInstance().setAisInfo(aisInfo);
   }
}
AIS_LOG.INFO("插入了:" + aisDataList.size() + "的ais数据");*/
// System.out.println("插入了:"+insert_num+"的ais数据。 更新了:"+updata_num);

//这是进行批操作,插入到数据库中.调用jdbc批处理。
DBCPHelper.batchInsert(aisDataList);
   }
  }




!!!注意,保存数据的类需要是线程安全的(通过单例+虚拟锁达到线程安全).如上述的AisHistoryServiceFactory类
通过这种方式就可以解决程序中得到大量数据。还需要将其大量数据保存到redis或者数据库中。


!!!注意,读取内存数据时,是分批次读取。如:每次读取1000条数据。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值