spring多線程demo

controller控制器

@RestController
@RequestMapping("/test")
public class TestController implements ApplicationContextAware {

    @Autowired
    private ServiceInvoke serviceInvoke;

    private ApplicationContext applicationContext;

    private int countA = 0;

    private ThreadLocal<Integer> countB=new ThreadLocal(){
        @Override
        protected Integer initialValue() {
            return 1;
        }
    };

    @RequestMapping(value = "/getReportLogo", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String getReportLogo() throws InterruptedException {
        long startTime=System.currentTimeMillis();
        List<AppReportBean> outList = new ArrayList<>();
        String outFile = "D:\\appstore4.5\\cscloud-appstore\\src\\main\\java\\com\\huawei\\cscloud\\appstore\\data\\utils\\execl\\file\\out.xlsx";
        String file = "D:\\appstore4.5\\cscloud-appstore\\src\\main\\java\\com\\huawei\\cscloud\\appstore\\data\\utils\\execl\\file\\test22.xlsx";
        long readFileStartTime=System.currentTimeMillis();
        List<AppReportBean> list = ExcelReader.readExcel(file);
        System.out.println("----------------------------------------------------------------------------");
        System.out.println("-----------"+"讀取文件所花時間秒:"+String.valueOf((System.currentTimeMillis()-readFileStartTime)/1000)+"---------");
        System.out.println("------------------------------------------------------------------------------");
        ReportSycnCount reportSycnCount=applicationContext.getBean(ReportSycnCount.class);
        CountDownLatchService countDownLatchService=applicationContext.getBean(CountDownLatchService.class);
        countDownLatchService.setCountDownLatch(new CountDownLatch(list.size()));
        reportSycnCount.setInList(list);
        ExecutorService executorService= Executors.newFixedThreadPool(20);

        for (int i = 0; i < list.size(); i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    ThreadService threadService=applicationContext.getBean(ThreadService.class);
                    threadService.serviceRun();
                }
            });
        }

        countDownLatchService.await();
        System.out.println(JSONObject.toJSON(reportSycnCount.getOutList()).toString());

        ExcelReader.writeExcel(reportSycnCount.getOutList(), 5, outFile);

        System.out.println("----------------------------------------------------------------------------");
        System.out.println("--------------"+"總共測試條數:"+countDownLatchService.getTotalCount()+"----------------------------------------------");
        System.out.println("-----------------"+"接口總共所花時間:"+String.valueOf((System.currentTimeMillis()-startTime)/1000)+"S---------------");
        System.out.println("----------------------------------------------------------------------------");
        JSONObject result=new JSONObject();
        result.put("data",reportSycnCount.getOutList());
        result.put("totalCount",reportSycnCount.getOutList().size());
        return JSONObject.toJSON(result).toString();


       /* String message = new String();
        for (int i = 0; i < list.size(); i++) {

            String logo = list.get(i).getReportLogo();

            if (StringUtils.isEmpty(logo)) {
                break;
            }
            String mediaId = logo.substring(logo.lastIndexOf("/") + 1);
            message = serviceInvoke.getHttpBody("http://beta-chn.threecloud.huawei.com/cscloud-media-service/media/getLogo/" + mediaId, String.class);

            if (StringUtils.isEmpty(message)) {
                System.out.println(JSONObject.toJSON(list.get(i)).toString());
                outList.add(list.get(i));
            }

        }*/


    }

    @RequestMapping(value = "/hello", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String getHello(HttpServletRequest request){
        String ip=getIpAdrress(request);
        System.out.println("-----------------------------------------------------------------");
        System.out.println("----------------"+"ipAddress is :"+ip+"--------------");
        System.out.println("-----------------------------------------------------------------");
        return "hello world!!!";
    }

    @RequestMapping(value = "/threadTest", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String threadTest(HttpServletRequest request){
        JSONObject result=new JSONObject();
        System.out.println("-----------------------------------------------------------------");
        try {
            Thread.sleep(2000);
            System.out.println("-----------------------------"+this.getClass().getName()+"-------------------------------");
            System.out.println("-----------------------------"+this+"-------------------------------");
            System.out.println("-----------------------------------------------------------------");
            result.put("countA",countA++);
            result.put("countB",countB.get()+1);
            return JSONObject.toJSON(result).toString();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "";
    }

    @RequestMapping(value = "/dataTest", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    public String dataTest(HttpServletRequest request){
        JSONObject result=new JSONObject();
        System.out.println("-----------------------------------------------------------------");
        String res = "";
        res = serviceInvoke.getHttpBody("http://localhost:8085/cscloud-central-resources/resources/apps/test111",  String.class);
        result = JSON.parseObject(res);

        String nameCn = result.getString("resName");
        String nameEn = result.getString("resNameEn");

        HashMap<String, String> map = Maps.newHashMap();
        map.put("shopNameCn", nameCn);
        map.put("shopNameEn", nameEn);

        return JSONObject.toJSON(map).toString();

    }

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

    public  String getIpAdrress(HttpServletRequest request) {
        String ip = null;

        //X-Forwarded-For:Squid 服務代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        String unknown = "unknown";
        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP:apache 服務代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP:weblogic 服務代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP:有些代理服務器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP:nginx服務代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些網絡通過多層代理,那麼獲取到的ip就會有多個,一般都是通過逗號(,)分割開來,並且第一個ip爲客戶端的真實IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }

        //還是不能獲取到,最後再通過request.getRemoteAddr();獲取
        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

}

service  線程服務(定義爲prototype類型的service bean)和countdownlatch服務(保障線程執行完畢)

@Component
@Scope("prototype")
public class ThreadService {
    @Autowired
    private ReportSycnCount reportSycnCount;

    @Autowired
    private ServiceInvoke serviceInvoke;

    @Autowired
    private CountDownLatchService countDownLatch;

    private static final CSCloudLog log = CSCloudLog.getLogger(AppSpecialOtherAction.class);

    List<AppReportBean> list;

    public void serviceRun() {
        try {
            String message = "";
            int count = reportSycnCount.getSyncCount();
            list = reportSycnCount.getInList();
            int inListSize = list.size();
            if (count < inListSize) {

                log.info("線程名稱:"+Thread.currentThread().getName()+"-----"+"執行數據:"+JSONObject.toJSON(list.get(count)).toString());
                String logo = list.get(count).getReportLogo();

                if (StringUtils.isEmpty(logo)) {
                    return;
                }
                String mediaId = logo.substring(logo.lastIndexOf("/") + 1);
               // message = serviceInvoke.getHttpBody("http://beta-chn.threecloud.huawei.com/cscloud-media-service/media/getLogo/" + mediaId, String.class);
                message = serviceInvoke.getHttpBody("http://chn.threecloud.huawei.com/cscloud-media-service/media/getLogo/" + mediaId, String.class);
                if (StringUtils.isEmpty(message)) {
                    System.out.println(JSONObject.toJSON(list.get(count)).toString());
                    reportSycnCount.writrOutList(list.get(count));
                }
                countDownLatch.setTotalCount(countDownLatch.getTotalCount()+1);
            }
        } finally {
            countDownLatch.countDown();
        }
    }
}
@Service
public class CountDownLatchService {

    private int totalCount=0;

    private CountDownLatch countDownLatch;

    public void countDown(){
        countDownLatch.countDown();
    }

    public void await() throws InterruptedException {
        countDownLatch.await();
    }

    public CountDownLatch getCountDownLatch() {
        return countDownLatch;
    }

    public void setCountDownLatch(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }
}

同步控制的線程業務類

@Component
public class ReportSycnCount {
    private List<AppReportBean> inList;
    private List<AppReportBean> outList = new ArrayList<>();
    private int count;

    private Lock getCountLock = new ReentrantLock();

    private Lock writeListLock = new ReentrantLock();

    public int getSyncCount() {
        try {
            getCountLock.lock();
            int a = getCount();
            setCount(a + 1);
            return a;
        } finally {
            getCountLock.unlock();
        }
    }

    public void writrOutList(AppReportBean appReportBean) {
        try {
            writeListLock.lock();
            outList.add(appReportBean);
        } finally {
            writeListLock.unlock();
        }
    }

    public List<AppReportBean> getInList() {
        return inList;
    }

    public void setInList(List<AppReportBean> inList) {
        this.inList = inList;
    }

    public List<AppReportBean> getOutList() {
        return outList;
    }

    public void setOutList(List<AppReportBean> outList) {
        this.outList = outList;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

excel操作工具類

public class ExcelReader {

    private static final String XLS = "xls";
    private static final String XLSX = "xlsx";

    /**
     * 根據文件後綴名類型獲取對應的工作簿對象
     * @param inputStream 讀取文件的輸入流
     * @param fileType 文件後綴名類型(xls或xlsx)
     * @return 包含文件數據的工作簿對象
     * @throws IOException
     */
    public static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException {
        Workbook workbook = null;
        if (fileType.equalsIgnoreCase(XLS)) {
            workbook = new HSSFWorkbook(inputStream);
        } else if (fileType.equalsIgnoreCase(XLSX)) {
            workbook = new XSSFWorkbook(inputStream);
        }
        return workbook;
    }

    /**
     * 讀取Excel文件內容
     * @param fileName 要讀取的Excel文件所在路徑
     * @return 讀取結果列表,讀取失敗時返回null
     */
    public static List<AppReportBean> readExcel(String fileName) {

        Workbook workbook = null;
        FileInputStream inputStream = null;

        try {
            // 獲取Excel後綴名
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            // 獲取Excel文件
            File excelFile = new File(fileName);
            if (!excelFile.exists()) {
                System.out.println("指定的Excel文件不存在!");
                return null;
            }

            // 獲取Excel工作簿
            inputStream = new FileInputStream(excelFile);
            workbook = getWorkbook(inputStream, fileType);

            // 讀取excel中的數據
            List<AppReportBean> resultDataList = parseExcel(workbook);

            return resultDataList;
        } catch (Exception e) {
            System.out.println("解析Excel失敗,文件名:" + fileName + " 錯誤信息:" + e.getMessage());
            return null;
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception e) {
                System.out.println("關閉數據流出錯!錯誤信息:" + e.getMessage());
                return null;
            }
        }
    }

    /**
     * 解析Excel數據
     * @param workbook Excel工作簿對象
     * @return 解析結果
     */
    private static List<AppReportBean> parseExcel(Workbook workbook) {
        List<AppReportBean> resultDataList = new ArrayList<>();
        // 解析sheet
        for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
            Sheet sheet = workbook.getSheetAt(sheetNum);

            // 校驗sheet是否合法
            if (sheet == null) {
                continue;
            }

            // 獲取第一行數據
            int firstRowNum = sheet.getFirstRowNum();
            Row firstRow = sheet.getRow(firstRowNum);
            if (null == firstRow) {
                System.out.println("解析Excel失敗,在第一行沒有讀取到任何數據!");
            }

            // 解析每一行的數據,構造數據對象
            int rowStart = firstRowNum + 1;
            int rowEnd = sheet.getPhysicalNumberOfRows();
            for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                Row row = sheet.getRow(rowNum);

                if (null == row) {
                    continue;
                }

                AppReportBean resultData = convertRowToData(row);
                if (null == resultData) {
                    System.out.println("第 " + row.getRowNum() + "行數據不合法,已忽略!");
                    continue;
                }
                resultDataList.add(resultData);
            }
        }

        return resultDataList;
    }

    /**
     * 提取每一行中需要的數據,構造成爲一個結果數據對象
     *
     * 當該行中有單元格的數據爲空或不合法時,忽略該行的數據
     *
     * @param row 行數據
     * @return 解析後的行數據對象,行數據錯誤時返回null
     */
    private static AppReportBean convertRowToData(Row row) {
        AppReportBean resultData = new AppReportBean();

        Cell cell;
        int cellNum = 0;
        // 獲取appid
        cell = row.getCell(cellNum++);
        String appId = convertCellValueToString(cell);
        resultData.setAppId(appId);
        cell = row.getCell(cellNum++);
        String author =  convertCellValueToString(cell);
        resultData.setAuthor(author);
        cell = row.getCell(cellNum++);
        String authorName =  convertCellValueToString(cell);
        resultData.setAuthorName(authorName);
        // 獲取reportId
        cell = row.getCell(cellNum++);
        String reportId =  convertCellValueToString(cell);
        if (null == reportId || "".equals(reportId)) {
            // 年齡爲空
            resultData.setReportId(null);
        } else {
            resultData.setReportId(reportId);
        }
        // 獲取reportName
        cell = row.getCell(cellNum++);
        String reportName = convertCellValueToString(cell);
        resultData.setReportName(reportName);
        // 獲取logo
        cell = row.getCell(cellNum++);
        String logo = convertCellValueToString(cell);
        resultData.setReportLogo(logo);

        return resultData;
    }

    /**
     * 將單元格內容轉換爲字符串
     * @param cell
     * @return
     */
    private static String convertCellValueToString(Cell cell) {
        if(cell==null){
            return null;
        }
        String returnValue = null;
        switch (cell.getCellType()) {
            case NUMERIC:   //數字
                Double doubleValue = cell.getNumericCellValue();

                // 格式化科學計數法,取一位整數
                DecimalFormat df = new DecimalFormat("0");
                returnValue = df.format(doubleValue);
                break;
            case STRING:    //字符串
                returnValue = cell.getStringCellValue();
                break;
            case BOOLEAN:   //布爾
                Boolean booleanValue = cell.getBooleanCellValue();
                returnValue = booleanValue.toString();
                break;
            case BLANK:     // 空值
                break;
            case FORMULA:   // 公式
                returnValue = cell.getCellFormula();
                break;
            case ERROR:     // 故障
                break;
            default:
                break;
        }
        return returnValue;
    }

    public static void writeExcel(List<AppReportBean> dataList, int cloumnCount,String finalXlsxPath){
        OutputStream out = null;
        try {
            String fileType = finalXlsxPath.substring(finalXlsxPath.lastIndexOf(".") + 1, finalXlsxPath.length());
            // 獲取總列數
            int columnNumCount = cloumnCount;
            // 讀取Excel文檔
            File finalXlsxFile = new File(finalXlsxPath);
            FileInputStream fileInputStream=new FileInputStream(finalXlsxFile);
            Workbook workBook = getWorkbook(fileInputStream,fileType);
            // sheet 對應一個工作頁
            Sheet sheet = workBook.getSheetAt(0);


            int rowNumber = sheet.getLastRowNum();    // 第一行從0開始算
            System.out.println("原始數據總行數,除屬性列:" + rowNumber);
            for (int i = 1; i <= rowNumber; i++) {
                Row row = sheet.getRow(i);
                sheet.removeRow(row);
            }
            // 創建文件輸出流,輸出電子表格:這個必須有,否則你在sheet上做的任何操作都不會有效
            out =  new FileOutputStream(finalXlsxPath);
            workBook.write(out);


            for (int j = 0; j < dataList.size(); j++) {
                // 創建一行:從第二行開始,跳過屬性列
                Row row = sheet.createRow(j + 1);
                // 得到要插入的每一條記錄
                AppReportBean dataMap = dataList.get(j);

                String appId = dataMap.getAppId();
                String author = dataMap.getAuthor();
                String authorName = dataMap.getAuthorName();
                String reportId = dataMap.getReportId();
                String reportName = dataMap.getReportName();
                String logo=dataMap.getReportLogo();


                for (int k = 0; k <= columnNumCount; k++) {
                    // 在一行內循環
                    Cell first = row.createCell(0);
                    first.setCellValue(appId);

                    Cell second = row.createCell(1);
                    second.setCellValue(author);

                    Cell third = row.createCell(2);
                    third.setCellValue(authorName);

                    Cell four = row.createCell(3);
                    four.setCellValue(reportId);

                    Cell five = row.createCell(4);
                    five.setCellValue(reportName);

                    Cell six = row.createCell(5);
                    six.setCellValue(logo);

                }
            }
            // 創建文件輸出流,準備輸出電子表格:這個必須有,否則你在sheet上做的任何操作都不會有效
            out =  new FileOutputStream(finalXlsxPath);
            workBook.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            try {
                if(out != null){
                    out.flush();
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("數據導出成功");
    }


}

bean


public class AppReportBean {

    private String appId;
    private String author;
    private String authorName;
    private String reportId;
    private String reportName;
    private String reportLogo;

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getReportId() {
        return reportId;
    }

    public void setReportId(String reportId) {
        this.reportId = reportId;
    }

    public String getReportName() {
        return reportName;
    }

    public void setReportName(String reportName) {
        this.reportName = reportName;
    }

    public String getReportLogo() {
        return reportLogo;
    }

    public void setReportLogo(String reportLogo) {
        this.reportLogo = reportLogo;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getAuthorName() {
        return authorName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章