大规模数据运行时,可以考虑使用多线程处理!

今年3月份测试了一段代码,数据库中有300万条数据,抽出处理后写入文件中。

 

大规模数据执行时,希望24小时内执行完毕,但是实际测试中,时间达到了27个小时之多。

---------------------------

---------------------------

 

今天又看到了这段代码,发现他们应该已经解决了这个问题。

 

他们解决的方式是才有多线程进行处理。(以下的①,②,③ 三大块)

 

好处

不但可以提高速度,当有文件出力时,还可以减轻每个文件的大小。

根据每条数据内容多少的不同,有时300万达到400多M,

但有时,400万条数据会达到1.2G之多。

 

当你的数据量时1.2G的文件时,你的机器不好,就很难打开这个文件。

使用多线程时,会生成多个文件,这样每个文件的大小也相应的减小。

(使用sakura,400M的文件打开,现在的机器HP OPTIPLEX 780是没有问题的,

但是1.2G的文件就无法打开。)

 

①整体的处理流程

ResultSet userInfoList = getUserInfoList();

// 建立一个数据池,这个数据池取出数据时是同步的。
// 也就是是说,10个线程都从这里取出数据,
// 但是,在同一时刻,只能有一个线程取数据。
 UserInfoSetPool userInfoSet = new UserInfoSetPool(userInfoList);

List<Thread>  threadList = new ArrayList<Thread>();
List<BT001Thread>  threadList = new ArrayList<BT001Thread>();

for(int i=0, i<10, i++ ){

     BT001Thread thread = new BT001Thread(fileDir, FileName + i );
     logicThreadList.add(thread);
     Thread th = new(thread);
     // 具体的业务处理,在线程类的run方法中进行处理。
     // 以为这些业务处理涉及到一些DB,文件读写操作,浪费时间。
     // 分成多线程来执行,就快多了!
     th.start();
     threadList.add(th);

}

//NEXT
//ERROR 
//END


boolean runFlag = true;
// 不断检查处理中线程的状态。 
while(runFlag){

     int i = 0;

     for(TestThread thread : logicThreadList){

          if(ERROR) {
                ....;
          } else if (NEXT){
                break;
          } else if (END) {
               i++;
          }

          if( i >= 10 ){
                // 十个线程都结束了,表明数据已经处理完毕。
                runFlag = false;
          }
     }

}


for(Thread thread:threadList){
    // 结束所有的线程。
    thread.join();
}

 

②供多个线程使用的数据池
 UserInfoSetPool

public class UserInfoSetPool {
    ResultSet userInfoList ;
    
    public UserInfoSetPool(ArrayList userInfoList){
         this.userInfoList = userInfoList;
    }
    

    /**
     * 使线程间能同步从数据池中取得数据。
     */
    public synchronized Map getUserInfo(){

        Map<String, String> userInfo = null;
        if(userInfoList.hasNext()){
            userInfo = new HashMap<String, String>();
            userInfo.put("userId",userInfoList.get("user_id"));
            ....
        }
        return userInfo;
    
    }
}

 

 

 

 

③线程类,从数据池中读取数据,对每天数据进行相应的业务处理。

 (真正的业务处理就在这里!!)

BT001Thread

public class BT001 extends Thread {
    public String STATUS_ERROR = "ERROR";
    public String STATUS_NEXT = "NEXT";
    public String STATUS_END = "END";
    // 数据池
    public UserInfoSetPool userInfoSetPool = null;
    

    /**
     * 构造方法,初始化数据池
     */
    public BT0001(UserInfoSetPool userInfoSetPool, String fileDir, String fileName) {
    	this.userInfoSetPool = userInfoSetPool;
    	
    }
   

    /**
     * 线程的run方法
     */
    public void run() {
      status = NEXT;

      try{
            boolean loopFlag = true;

            //让线程一直执行下去.
            while(loopFlag){ // 从数据池中获取数据。 
            
      
                Map userInfo = userInfoSetPool.getUserInfo(); 
                if(userInfo ==null ) {
                    loopFlag = false;
                } else {
             
                     .....//业务处理 

                }
            }// end while

            status = END;              

        } catch(){
           
             status = ERROR;
        }
    }

    /**
     * 取得线程的状态
     */
    public getThreadStatus(){
        .....;
    } 

}


 

。。。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值