一个简单的多线程实现

1、配置扫描的类,线程使用的ApplicationContextUtils需要被扫描到

<context:component-scan base-package="com.glanway.zpparts.controller,com.glanway.zpparts.test"/>

一个简单的多线程实现

2、编写一个ApplicationContextUtils对象的类,与上面设置的路径对应

 package com.glanway.zpparts.test;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextUtils implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtils.setApplicationContext(applicationContext);
    }

}

3、编写一个获取Sservice的SpringUtils工具类,路径与上面配置的对应

 package com.glanway.zpparts.test;

import org.springframework.context.ApplicationContext;

/**
 * 注入获取service对象
 * @author zp_ww
 * @date 2019年3月25日
 */
public class SpringUtils {
     
     private static ApplicationContext applicationContext;
     
     public static void setApplicationContext(ApplicationContext applicationContext) {
         SpringUtils.applicationContext = applicationContext;
     }
     
     public static ApplicationContext getApplicationContext() {
         return SpringUtils.applicationContext;
     }

}

4、编写一个创建线程池的类

 package com.glanway.zpparts.test;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 创建线程池
 * @author zp_ww
 * @date 2019年3月25日
 */
public class ThreadPoolHelper {
     
     private static ThreadPoolExecutor threadPoolExecutor;
     
     static {
         // 设置线程池同时进行的线程数、创建的线程数、失效时间
         threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
     }
     
     public static void execute(Runnable runnable) {
         threadPoolExecutor.execute(runnable);
     }

}

5、创建一个正确数据跑的线程方法

 package com.glanway.zpparts.test;

import java.util.List;

import org.apache.poi.ss.usermodel.Row;
import org.springframework.context.ApplicationContext;

import com.glanway.zpparts.service.wyyx.WyYxUserService;

/**
 * 正确线程实现类
 * @author zp_ww
 * @date 2019年3月25日
 */
public class ExcelTask implements Runnable {
     
    //开始索引
    private int startIndex;
    
    //处理的条数
    private int total;
    
    //sheet
    private List<Row> row;
    
    public ExcelTask(List<Row> row, int startIndex, int total) {
        this.startIndex = startIndex;
        this.row = row;
        this.total = total;
    }

    
    /**
     * 线程的实现方法
     */
    @Override
    public void run() {
        //WyYxUserService wyyxUserService = SpringUtils.getBean(WyYxUserService.class);
        //WyyxUser user = wyyxUserService.getWyYxUserByMemberId(Long.valueOf(16));
        //ZppartsServiceUtilTwo.getService();
        
        ApplicationContext applicationContext = SpringUtils.getApplicationContext();
        // 获取service
        WyYxUserService wyYxUserService = applicationContext.getBean(WyYxUserService.class);
        System.out.println(wyYxUserService);
        System.out.println(wyYxUserService.getWyYxUserByMemberId(Long.valueOf(16)));
        
//        WyyxUser user = ZppartsServiceUtils.getZppartsServiceUtils().getWyYxUserService().getWyYxUserByMemberId(Long.valueOf(16));
//        System.out.println(user.getName());
//        System.out.println(Thread.currentThread().getName() + " 处理成功数据:"+startIndex + ":" + (startIndex + total));
//        for (int i = startIndex; i < total; i++) {
//            
//        }
         
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public List<Row> getRow() {
        return row;
    }

    public void setRow(List<Row> row) {
        this.row = row;
    }
    
}

6、创建一个错误数据跑的线程实现类

 package com.glanway.zpparts.test;

import java.util.List;

import org.apache.poi.ss.usermodel.Row;

/**
 * 错误数据线程实现类
 * @author zp_ww
 * @date 2019年3月25日
 */
public class ExcelErrorTask implements Runnable {
     
    //sheet
    private List<Row> row;
    
    public ExcelErrorTask(List<Row> row) {
        this.row = row;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 处理失败数据:" + row.size());
    }

    public List<Row> getRow() {
        return row;
    }

    public void setRow(List<Row> row) {
        this.row = row;
    }

}

7、编写一个测试类

package com.glanway.zpparts.test;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * 线程测试
 * @author zp_ww
 * @date 2019年3月25日
 */
public class ExcelUpload {

    public static List<Row> resultList = new ArrayList<>();

    public static List<Row> errorList = new ArrayList<>();

    public static void test() throws Exception {
        
        long startTime = System.currentTimeMillis();

        Set<String> heavySet = new HashSet<String>();
        int lastSize = 0;

        File file =
            new File("C:/Users/zp_ww/Documents/WeChat Files/Files/数据/数据", "商品导入测试.xlsx");
        FileInputStream inputStream = new FileInputStream(file);
        XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
        
        System.out.println("读取文件耗时: " + (System.currentTimeMillis() - startTime));

        Sheet sheet = workbook.getSheetAt(0);
        int rowNumber = sheet.getLastRowNum(); // 第一行从0开始算

        for (int i = 1; i <= rowNumber; i++) {
            Row row = sheet.getRow(i);
            row.getCell(4).setCellType(Cell.CELL_TYPE_STRING);
            row.getCell(7).setCellType(Cell.CELL_TYPE_STRING);
            String stringCellValue = row.getCell(4).getStringCellValue().replace(" ", "");
            String stringCellValue2 = row.getCell(7).getStringCellValue().replace(" ", "");
            heavySet.add(stringCellValue + stringCellValue2);
            if (heavySet.size() == lastSize) {
                // 插入失敗
                errorList.add(row);
            } else {
                // 插入成功
                resultList.add(row);
                lastSize = heavySet.size();
            }
        }
        
        System.out.println("文件去重耗时: " + (System.currentTimeMillis() - startTime));

        int resultListSize = resultList.size();
        // 每个线程最低执行的行数
        int count = (int)(resultListSize / 5);
        // 多余的行数
        int num = resultListSize - (count * 5);
        for (int i = 0; i < 5; i++) {
            if (i == 4) {
                // 创建一个线程
                ThreadPoolHelper.execute(new ExcelTask(resultList, count * i, count + num));
            } else {
                ThreadPoolHelper.execute(new ExcelTask(resultList, count * i, count));
            }
        }
        ThreadPoolHelper.execute(new ExcelErrorTask(errorList));

    }

}