線程池分批處理excel數據

1、場景

  在開發excel處理數據時,由於數據庫的卡頓,一次插入2000條數據速度可能須要1min左右,因此考慮使用線程池;每200個分組,有n組,就開(n+1)個線程去分批同時處理這些數據。java

2、依賴

1. pom.xmlmysql

        <!--工具類hutool,java兵器庫,用於讀取excel-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.5.10</version>
        </dependency>    

2. excel的表格只有一個字段就是keyword,示例以下:sql

3. 數據庫:t_keyword(只有一個字段keyword,而且加惟一索引)數據庫

 

3、代碼

dao.java

package com.bds.pool.ihg_fb;

import org.nutz.dao.impl.NutDao;
import org.nutz.dao.impl.SimpleDataSource;

/**
 * @ClassName:         Dao.java
 * @Description:  
 * @author :         jack.Lu
 * @version :         V1.0  
 * @Date :             2019年7月11日 下午5:08:13 
 */
public class Dao {
    
    public static NutDao getDao() {
        // 建立一個數據源
        SimpleDataSource dataSource = new SimpleDataSource();
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1/bds");
        dataSource.setUsername("root");
        dataSource.setPassword("root");

        // 建立一個NutDao實例,在真實項目中, NutDao一般由ioc託管, 使用注入的方式得到.
        NutDao dao = new NutDao(dataSource);
        return dao;
    }

}

dealExcel.java

package com.bds.pool.ihg_fb;

import java.util.ArrayList;
import java.util.List;

import org.nutz.dao.impl.NutDao;

/**
 * @ClassName:         DealExcel.java
 * @Description:  
 * @author :         jack.Lu
 * @version :         V1.0  
 * @Date :             2019年7月11日 下午2:18:48 
 */
public class DealExcel implements Runnable{
    
    List<String> list;
    
    private String thread_name;
    
    private Boolean success=false;
    
    public DealExcel(String thread_name,List<String> list) {
        this.thread_name = thread_name;
        this.list=list;
    }
    
    public int deal() {
        List<KeyWord> list_k = new ArrayList<>();
        KeyWord k = new KeyWord();
        NutDao dao = Dao.getDao();
        for(String s : list) {
            k.setKeyword(s);
            try {
                dao.insert(k);
            } catch (Exception e) {
                System.out.println(s+">>>>>>>>>>>已經插入!");
            }
        }
        
        return list.size();
    }

    @Override
    public void run() {
        System.out.println(this.thread_name+"***********"+Thread.currentThread().getName()+"開始處理....");
        int deal = this.deal();
        success = true;
        System.out.println(this.thread_name+"***********"+Thread.currentThread().getName()+"處理完成"+deal+"條數據");
    }

    public Boolean getSuccess() {
        return success;
    }

    public String getThread_name() {
        return thread_name;
    }
    
    
    
}

KeyWord.java

package com.bds.pool.ihg_fb;

import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Table;

/**
 * @ClassName:         KeyWord.java
 * @Description:  
 * @author :         jack.Lu
 * @version :         V1.0  
 * @Date :             2019年7月11日 下午5:09:54 
 */
@Table("t_keyword")
public class KeyWord {
    @Column
    private String keyword;

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }
    

}

PoolThread.java

package com.bds.pool.ihg_fb;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;

/**
 * @ClassName:         PoolThread.java
 * @Description:      開啓線程池
 * @author :         jack.Lu
 * @version :         V1.0  
 * @Date :             2019年7月11日 下午2:18:35 
 */
public class PoolThread {
    /**
   *程序的入口
   */
public static void main(String args[])throws Exception{ readExcel(); } /** * 1.讀取excel * 2.對excel進行200分段 * 3.開啓線程池 * @param args */ public static void readExcel(){ //1.讀取excel ExcelReader excelReader = ExcelUtil.getReader(FileUtil.file("C:\\Users\\admin\\Desktop\\新建文件夾\\XHS 筆記需求 0709-03.xlsx")); List<Map<String,Object>> read = excelReader.readAll(); PoolThread pl = new PoolThread(); List<List<String>> excelByRead = pl.getExcelByRead(read);//500條數據,每200一條,共3組 //要開啓的線程數//3組 int size = excelByRead.size(); ExecutorService pool = Executors.newFixedThreadPool(size+1); List<DealExcel> task_list = new ArrayList<DealExcel>(); for (int i = 0; i < size; i++) { List<String> list = excelByRead.get(i); DealExcel dx = new DealExcel(i+"-",list); task_list.add(dx); pool.execute(dx); } //結束線程池 pool.shutdown(); while(true) { if(pool.isTerminated()) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } String s = ""; for(DealExcel d : task_list) { s= s+d.getThread_name()+":"+(d.getSuccess()?"成功":"失敗")+";"; } System.out.println("----------------------------------------------"); System.out.println(s); } /** * 以200爲臨界點 每200個放入一個String數組中,再放入List 集合中 * @param read * @return */ private List<List<String>> getExcelByRead(List<Map<String,Object>> read) { List<List<String>> list_list = new ArrayList<>(); int size = read.size(); int group = 200; int num = size/group; if(size%group!=0) {//說明不是整數101-》1+1=2 num = num +1; } System.out.println("準備建立幾個數組就是開啓多少線程:"+num); //開始遍歷excel int temp = 0; for (int j = 1; j <= num; j++) { List<String> list = new ArrayList<>(); for (int i = temp; i < size; i++) { Map<String, Object> map = read.get(i); String keyword = map.get("keyword")+""; list.add(keyword); if ((i+1)%group==0) { temp=i+1; break; } } System.out.println("*****已經加入集合"+j+"次"); list_list.add(list); } System.out.println("########################添加結束##################################"); return list_list; } }

 學習總結:多種線程池的使用區別是他們的參數不一樣使用場景不一樣,在學習線程池的時候,到網上搜索全部的案例,可是發現所有都是分析線程池的區別,解剖源碼,開始分析他們的體系,要麼就是文章所有都是同樣的東西,重複論述,巴拉巴拉。。。確實沒有一個使用場景可讓好好參考,因而本身硬是想了一個場景,不知道效果如何可是確實聯繫了第一次寫線程池來處理業務。但願有錯能夠給我及時指出來。謝謝!數組

相關文章
相關標籤/搜索